RSA.js_公钥加密_NoPadding_golang实现_n_e_pem格式互转
转载注明来源: 本文链接 来自osnosn的博客,写于 2021-09-13.
参考
- PKCS1【Golang 实现RSA加密解密】
- PKCS1,密钥格式转换(需第三方包)【RSA非对称加密算法实现:Golang】
- 【RSA算法原理】【RSA公钥指数的选取】
- N:modulus, E:public exponent, D:private exponent.
- N:两个质数的乘积; E:选取的指数,通常选3,17,65537; D:模反元素; (N,E)为公钥; (N,D)为私钥;
M:明文, C:密文, 要求 M<N;
公钥加密: C=((M^E) mod N), M的E次方除以N的余数=C;
密钥解密: M=((C^D) mod N), C的D次方除以N的余数=M;
- go 实现 js 的 encodeURIComponent() 函数【golang encodeURIComponent】
- PKCS1【Go进阶18:常用加密解密算法总结AES/DES/RSA/Sha1/Sha256/MD5】【Go加密算法总结】
- golang中用N,E创建公钥【Golang PublicKey.E方法代码示例】【How to parse public key with N= and E= in golang】
- 用py3,把N,E转换为PEM格式公钥【已知rsa的模数和指数 生成pem公钥文件】【Python从二进制文件中提取Exponent和Modulus数据(e, n)并构建公钥】
- golang rsa nopadding 【golang rsa decrypt no padding】【golang rsa解密没有填充】【NoPadding填充方式的RSA加密,用Java和Golang实现】
- 【openssl的RSA使用】
openssl 生成 rsa 密钥对
- 生成rsa私钥,
openssl genrsa -out rsakey.pem 1024
- 生成rsa公钥,
openssl rsa -in rsakey.pem -pubout -out rsapubkey.pem
golang 例子
- 其中 RsaEncryptNopadding() 的加密结果,
对比 JavaScript 中, 用 Barrett.js, BigInt.js, RSA.js (Copyright 1998-2005 David Shapiro.) 脚本加密的结果相同。 - 新版的 RSA.js 已经支持 PKCS1v1.5 的 padding 了。就不需要这种 nopadding 的算法了。用 RsaEncryptPkcs1( )。
- RsaEncryptOAEP( ) , OAEP 方式。
- 例程中演示了,读入 PEM 格式公钥,输出 N, E。
- readNE( ) 和 pubkey_to_pem( ) , 可以实现公钥 N, E 转为 PEM 格式。
package main
import (
"crypto/rand"
"crypto/rsa"
"crypto/sha1"
"crypto/x509"
"encoding/hex"
"encoding/pem"
"errors"
"fmt"
"io/ioutil"
"math/big"
"net/url"
"os"
"strconv"
"strings"
)
func readPEM(file string) (*rsa.PublicKey, error) {
// 读取公匙文件
pubByte, err := ioutil.ReadFile(file)
if err != nil {
return nil, err
}
// pem解码
block, _ := pem.Decode(pubByte)
if block == nil {
return nil, errors.New("error public key")
}
// 解析公钥
pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return nil, err
}
// 类型断言
pubkey := pubInterface.(*rsa.PublicKey)
return pubkey, nil
}
func readNE(N string, E string) (*rsa.PublicKey, error) {
// 另一种创建pubkey的方法
E64, _ := strconv.ParseInt(E, 16, 32)
Eint := int(E64)
bigN := new(big.Int)
_, ok := bigN.SetString(N, 16)
if !ok {
panic("failed to parse")
}
pubkey := &rsa.PublicKey{
N: bigN,
E: Eint,
}
return pubkey, nil
}
func RsaEncryptPkcs1(pubkey *rsa.PublicKey, origData []byte) ([]byte, error) {
//加密
return rsa.EncryptPKCS1v15(rand.Reader, pubkey, origData)
}
func RsaEncryptNopadding(pubkey *rsa.PublicKey, origData []byte) string {
//反转明文
for from, to := 0, len(origData)-1; from < to; from, to = from+1, to-1 {
origData[from], origData[to] = origData[to], origData[from] //反转字符串
}
//加密,这里需要判断 len(明文)<=(N.BitLen()/8-2), 否则就要分组加密。(本例程未作判断)
c := new(big.Int).SetBytes(origData)
encryptedBytes := c.Exp(c, big.NewInt(int64(pubkey.E)), pubkey.N).Bytes() // c的E次方 mod N
encryptedHex := hex.EncodeToString(encryptedBytes)
return encryptedHex
}
func RsaEncryptOAEP(pubkey *rsa.PublicKey, text string) string {
secretMessage := []byte(text)
rng := rand.Reader
cipherdata, err := rsa.EncryptOAEP(sha1.New(), rng, pubkey, secretMessage, nil)
if err != nil {
fmt.Printf("Error from encryption: %s
", err)
return ""
}
return hex.EncodeToString(cipherdata)
}
func pubkey_to_pem(pubkey *rsa.PublicKey, outfilename string) {
//输出pem格式的公钥
derPubkey, _ := x509.MarshalPKIXPublicKey(pubkey)
block := &pem.Block{
Type: "PUBLIC KEY",
Bytes: derPubkey,
}
pemfile, _ := os.Create(outfilename)
_ = pem.Encode(pemfile, block)
pubkey_b := pem.EncodeToMemory(block)
fmt.Println(string(pubkey_b))
}
func encodeURIComponent(str string) string {
//JavaScript 的 encodeURIComponent()
r := url.QueryEscape(str)
r = strings.Replace(r, "+", "%20", -1)
return r
}
func main() {
var pubkey *rsa.PublicKey
var cleartxt, txt string
var data []byte
fmt.Println("------pubkey from pem-------")
pubkey, _ = readPEM("rsapubkey.pem")
fmt.Printf("BitLen:%d
", pubkey.N.BitLen())
fmt.Printf("E:%x
N:%x
", pubkey.E, pubkey.N.Bytes())
cleartxt = "abcdefg12345" //明文
fmt.Println("Clear text:", cleartxt)
fmt.Println("------rsa encrypt pkcs1-------")
data, _ = RsaEncryptPkcs1(pubkey, []byte(cleartxt))
fmt.Printf("=> %s
", hex.EncodeToString(data))
fmt.Println("------rsa encrypt nopadding-------")
txt = RsaEncryptNopadding(pubkey, []byte(cleartxt))
fmt.Printf("=> %s
", txt)
fmt.Println("------rsa encrypt oaep-------")
txt = RsaEncryptOAEP(pubkey, cleartxt)
fmt.Printf("=> %s
", txt)
fmt.Println("------pubkey from N,E:-------")
N := "b54a4cf3c2ceb6d34f6c45797528174901075fad452e7f0787ff82da82bd4f056685ad3c26fbd34e837c26792e100f29d065aa2a5c3a6222179d67df127038223ac7dd74a1f17f58b905702291273d8df12971692c4329225978839b32f08d299a770c1b60334f5ab7322f7cc90fc20f71c7aee0646e8ccfa7766bcde4db4087"
E := "10001"
pubkey, _ = readNE(N, E)
//fmt.Println(pubkey)
fmt.Printf("BitLen:%d
", pubkey.N.BitLen())
cleartxt = encodeURIComponent("abcdefg12345") //明文,且url编码
fmt.Println("Clear text:", cleartxt)
fmt.Println("------rsa encrypt pkcs1-------")
data, _ = RsaEncryptPkcs1(pubkey, []byte(cleartxt))
fmt.Printf("=> %s
", hex.EncodeToString(data))
fmt.Println("------rsa encrypt nopadding-------")
txt = RsaEncryptNopadding(pubkey, []byte(cleartxt))
fmt.Printf("=> %s
", txt)
fmt.Println("------rsa encrypt oaep-------")
txt = RsaEncryptOAEP(pubkey, cleartxt)
fmt.Printf("=> %s
", txt)
pubkey_to_pem(pubkey, "out_pubkey.pem")
fmt.Printf("--- Finished ---
")
}
- 执行结果
------pubkey from pem-------
BitLen:1024
E:10001
N:b54a4cf3c2ceb6d34f6c45797528174901075fad452e7f0787ff82da82bd4f056685ad3c26fbd34e837c26792e100f29d065aa2a5c3a6222179d67df127038223ac7dd74a1f17f58b905702291273d8df12971692c4329225978839b32f08d299a770c1b60334f5ab7322f7cc90fc20f71c7aee0646e8ccfa7766bcde4db4087
Clear text: abcdefg12345
------rsa encrypt pkcs1-------
=> 288263e8104bbe9f735bdc7a4403c28293084ea10adc1b0ad9ea285f003b1857cdbb90f900570fbfc06645fdadf644474607e5d71bfb3fd83346f67777d4fdc0ca0c081aaeb6a3b3540e3823c633ce77bb75169f92611dee5949fd84f0d5c3c1ad8bf85892307f076ff71ca35ea66516ff13a17e1feb2d4a37941e71cf6720eb
------rsa encrypt nopadding-------
=> 3795065bad6c9a54a3b7b558d64c75bf7236fc4e9c67503e2343d9e5c07b72540ce620e0962a968fe0a89e54aee0572582d50c97535e8e0e6bb2841e4f6465cbfbe779ad30aa6396e47a3157a2c01a9845f91d1c771468a3088c2fd776027c64ce767009096a91d5b65e9c4defab8c6b5713ced1266fd8a3679d9d1a35737d69
------rsa encrypt oaep-------
=> b480eb91196fa9f695aaf065658d56c2982dcfd56e323c2e061060c10cc0128541ec22943919c9c23a8a276d0a8450979a651450ee3f0d3252a9eae6803926ebd2e36c30593e8265b1119b74c9a37f940b8217551d573d1b8a71982e7a0929db4c8f0fc0cfbf4aff575e62c735db89e36f1453d01c123963459aa08c36f83516
------pubkey from N,E:-------
BitLen:1024
Clear text: abcdefg12345
------rsa encrypt pkcs1-------
=> 1959688e94ddaae83c83ae6ef531df1ac4eb142e2ca284501fe83b532297ddfb1f31d346fa88bcc59b368b9f5ec7f04a7693c6a022109a8fb861499059aacce4fd1ddc2908139102f9cc8948312f5f187c7d9bbf29c32bae71b4e0362f06f374f25f2396cbc91c760230911eae71416a51d0f6bacbe050663ba664d997e86648
------rsa encrypt nopadding-------
=> 3795065bad6c9a54a3b7b558d64c75bf7236fc4e9c67503e2343d9e5c07b72540ce620e0962a968fe0a89e54aee0572582d50c97535e8e0e6bb2841e4f6465cbfbe779ad30aa6396e47a3157a2c01a9845f91d1c771468a3088c2fd776027c64ce767009096a91d5b65e9c4defab8c6b5713ced1266fd8a3679d9d1a35737d69
------rsa encrypt oaep-------
=> a76804bef115d34a16fe81017e746f24c9e09da7cc2a24316980f6d265c66a212b0933c6d83915240894eb8c55dde77efb71f14ca147a5083962888ae4e90944d2c165da23116f03f6db7acbe78b51e5b8ca464aef3d81458263df5767b01ae683c6c2806424db61f750a345fb4e08e27ca087e40ca05403ae1dd63835c27784
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC1Skzzws62009sRXl1KBdJAQdf
rUUufweH/4Lagr1PBWaFrTwm+9NOg3wmeS4QDynQZaoqXDpiIhedZ98ScDgiOsfd
dKHxf1i5BXAikSc9jfEpcWksQykiWXiDmzLwjSmadwwbYDNPWrcyL3zJD8IPcceu
4GRujM+ndmvN5NtAhwIDAQAB
-----END PUBLIC KEY-----
--- Finished ---
python3, N E 转 pem
#!/usr/bin/python3
# -*- coding: utf-8 -*- #
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization
exponent=0x10001
modulus="b54a4cf3c2ceb6d34f6c45797528174901075fad452e7f0787ff82da82bd4f056685ad3c26fbd34e837c26792e100f29d065aa2a5c3a6222179d67df127038223ac7dd74a1f17f58b905702291273d8df12971692c4329225978839b32f08d299a770c1b60334f5ab7322f7cc90fc20f71c7aee0646e8ccfa7766bcde4db4087"
def populate_public_key(modulus, exponent):
n=int(modulus,16)
e=exponent
key=rsa.RSAPublicNumbers(e,n).public_key(default_backend())
return key
def generate_pub_key(pub_key, pem_name):
pem=pub_key.public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo
)
print(pem.decode())
#with open(pem_name,'w+') as f:
# f.writelines(pem.decode())
return pem
if __name__=='__main__':
pub_key=populate_public_key(modulus,exponent)
pem_file=r'pub_key.pem'
generate_pub_key(pub_key,pem_file)
转载注明来源: 本文链接 https://www.cnblogs.com/osnosn/p/15262557.html
来自 osnosn的博客 https://www.cnblogs.com/osnosn/ .