转载注明来源:本文链接 来自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 - 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 big.newint(int64(pubkey.e)), pubkey.n).bytes() c的e次方 mod n encryptedhex return } func rsaencryptoaep(pubkey *rsa.publickey, text string) string { secretmessage rng cipherdata, err rng, pubkey, secretmessage, nil) if !="nil" fmt.printf("error from encryption: %s\n", err) "" hex.encodetostring(cipherdata) pubkey_to_pem(pubkey outfilename 输出pem格式的公钥 derpubkey, _ block type: "public key", bytes: pemfile, block) pubkey_b fmt.println(string(pubkey_b)) encodeuricomponent(str javascript 的 encodeuricomponent() r "+", "%20", -1) main() var pubkey *rsa.publickey cleartxt, txt data []byte fmt.println("------pubkey pem-------") fmt.printf("bitlen:%d\n", pubkey.n.bitlen()) fmt.printf("e:%x\nn:%x\n", pubkey.e, pubkey.n.bytes()) cleartxt="abcdefg12345" 明文 fmt.println("clear text:", cleartxt) fmt.println("------rsa encrypt pkcs1-------") data, []byte(cleartxt)) fmt.printf("> %s\n", hex.EncodeToString(data))
fmt.Println("------rsa encrypt nopadding-------")
txt = RsaEncryptNopadding(pubkey, []byte(cleartxt))
fmt.Printf("=> %s\n", txt)
fmt.Println("------rsa encrypt oaep-------")
txt = RsaEncryptOAEP(pubkey, cleartxt)
fmt.Printf("=> %s\n", txt)
fmt.Println("------pubkey from N,E:-------")
N := "b54a4cf3c2ceb6d34f6c45797528174901075fad452e7f0787ff82da82bd4f056685ad3c26fbd34e837c26792e100f29d065aa2a5c3a6222179d67df127038223ac7dd74a1f17f58b905702291273d8df12971692c4329225978839b32f08d299a770c1b60334f5ab7322f7cc90fc20f71c7aee0646e8ccfa7766bcde4db4087"
E := "10001"
pubkey, _ = readNE(N, E)
//fmt.Println(pubkey)
fmt.Printf("BitLen:%d\n", 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\n", hex.EncodeToString(data))
fmt.Println("------rsa encrypt nopadding-------")
txt = RsaEncryptNopadding(pubkey, []byte(cleartxt))
fmt.Printf("=> %s\n", txt)
fmt.Println("------rsa encrypt oaep-------")
txt = RsaEncryptOAEP(pubkey, cleartxt)
fmt.Printf("=> %s\n", txt)
pubkey_to_pem(pubkey, "out_pubkey.pem")
fmt.Printf("--- Finished ---\n")
}
</=(n.bitlen()>
- 执行结果
`
=> 288263e8104bbe9f735bdc7a4403c28293084ea10adc1b0ad9ea285f003b1857cdbb90f900570fbfc06645fdadf644474607e5d71bfb3fd83346f67777d4fdc0ca0c081aaeb6a3b3540e3823c633ce77bb75169f92611dee5949fd84f0d5c3c1ad8bf85892307f076ff71ca35ea66516ff13a17e1feb2d4a37941e71cf6720eb
=> b480eb91196fa9f695aaf065658d56c2982dcfd56e323c2e061060c10cc0128541ec22943919c9c23a8a276d0a8450979a651450ee3f0d3252a9eae6803926ebd2e36c30593e8265b1119b74c9a37f940b8217551d573d1b8a71982e7a0929db4c8f0fc0cfbf4aff575e62c735db89e36f1453d01c123963459aa08c36f83516
=> 1959688e94ddaae83c83ae6ef531df1ac4eb142e2ca284501fe83b532297ddfb1f31d346fa88bcc59b368b9f5ec7f04a7693c6a022109a8fb861499059aacce4fd1ddc2908139102f9cc8948312f5f187c7d9bbf29c32bae71b4e0362f06f374f25f2396cbc91c760230911eae71416a51d0f6bacbe050663ba664d997e86648
=> a76804bef115d34a16fe81017e746f24c9e09da7cc2a24316980f6d265c66a212b0933c6d83915240894eb8c55dde77efb71f14ca147a5083962888ae4e90944d2c165da23116f03f6db7acbe78b51e5b8ca464aef3d81458263df5767b01ae683c6c2806424db61f750a345fb4e08e27ca087e40ca05403ae1dd63835c27784
Original: https://www.cnblogs.com/osnosn/p/15262557.html
Author: osnosn
Title: RSA.js_公钥加密_NoPadding_golang实现_n_e_pem格式互转
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/516602/
转载文章受原作者版权保护。转载请注明原作者出处!