RSA算法广泛应用与数据加密(比如 SSL 传输层加密),数字签名(比如支付宝的支付签名)。
1、加密解密
// encrypts the given message with RSA-OAEP
func f1() {// random 用来生成随机的素数rsaPriviteKey, err := rsa.GenerateKey(rand.Reader, 1024)if err != nil {log.Fatal(err)}str := "raoxiaoya"encdata, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, &rsaPriviteKey.PublicKey, []byte(str), nil)if err != nil {log.Fatal(err)}log.Println(hex.EncodeToString(encdata))decdata, err := rsa.DecryptOAEP(sha256.New(), nil, rsaPriviteKey, encdata, nil)if err != nil {log.Fatal(err)}log.Println(string(decdata))// 通用的 Decode 方法decdata2, err2 := rsaPriviteKey.Decrypt(rand.Reader, encdata, &rsa.OAEPOptions{Hash: crypto.SHA256, Label: nil})if err2 != nil {log.Fatal(err2)}log.Println(string(decdata2))
}// encrypts the given message with RSA and the padding scheme from PKCS #1 v1.5
func f2() {rsaPriviteKey, err := rsa.GenerateKey(rand.Reader, 1024)if err != nil {log.Fatal(err)}str := "raoxiaoya"encdata, err := rsa.EncryptPKCS1v15(rand.Reader, &rsaPriviteKey.PublicKey, []byte(str))if err != nil {log.Fatal(err)}log.Println(hex.EncodeToString(encdata))decdata, err := rsa.DecryptPKCS1v15(nil, rsaPriviteKey, encdata)if err != nil {log.Fatal(err)}log.Println(string(decdata))// 通用的 Decode 方法decdata2, err2 := rsaPriviteKey.Decrypt(rand.Reader, encdata, nil)if err2 != nil {log.Fatal(err2)}log.Println(string(decdata2))
}
2、数字签名
func f3() {rsaPriviteKey, err := rsa.GenerateKey(rand.Reader, 1024)if err != nil {log.Fatal(err)}str := []byte("raoxiaoya")// 由于 rsa 算法比较慢,所以先使用哈希算法来缩短加密的数据hashed := sha256.Sum256(str)// random 参数是预留问题,可以设置为nil// 使用私钥来签名signature, err := rsa.SignPKCS1v15(nil, rsaPriviteKey, crypto.SHA256, hashed[:])if err != nil {log.Fatal(err)}log.Println(hex.EncodeToString(signature))// 使用公钥来验证签名err = rsa.VerifyPKCS1v15(&rsaPriviteKey.PublicKey, crypto.SHA256, hashed[:], signature)log.Fatal(err)
}
3、将RSA密钥导出到PEM文件
func f4() {rsaPriviteKey, err := rsa.GenerateKey(rand.Reader, 1024)if err != nil {log.Fatal(err)}pri := x509.MarshalPKCS1PrivateKey(rsaPriviteKey)block := &pem.Block{Type: "RSA PRIVATE KEY",Bytes: pri,}file, err := os.Create("private.pem")if err != nil {log.Fatal(err)}err = pem.Encode(file, block)if err != nil {log.Fatal(err)}pub := x509.MarshalPKCS1PublicKey(&rsaPriviteKey.PublicKey)block2 := &pem.Block{Type: "PUBLIC KEY",Bytes: pub,}file2, err2 := os.Create("public.pem")if err2 != nil {log.Fatal(err2)}err2 = pem.Encode(file2, block2)if err2 != nil {log.Fatal(err2)}
}
文件内容如下
-----BEGIN RSA PRIVATE KEY-----
MIICXgIBAAKBgQDFgklwSCKCIdoMoPbRrS/kYAlHfbq6SyjBx+6rvQ8muGEBtt+n
SwQQEsPRGyIfe/bN/E0lh1iONqhO3z1qiQoOGc1mAlq3/So8dXOx3HWTGyhbvKZi
O/suGsjAx/OIrmeaHuypMK5uY2TXx0CI2a4h3JyQ/X9WzfCZRs3uZhAb6wIDAQAB
AoGBAKSTQMBnyyFmNbxKMABdcEe64mCI2pw63nZCM5U1DzfzcRmtmUVcE8GU8Uf/
dPqJIAlaD6qS0e6Gis5V5GYuVIoejjruEZDVLB/VULg3hqFrwHmjCxZ8tevQxAXf
nFMO0pycmLB4MIh2PlupSdN7QACAnFY/DQatiV7xjfHzll0hAkEA5ghQrDDEqLfn
fau5rK5K3+Gi8W8z++GMizWUnlxJMKrJycTcoYnDUFCb/W2Q39WTvEFNBSfSIzg3
iFqGXiEU0QJBANvOE7ySosZTGLoHptdueH3MMqN351QZ8okyCWwf9kQS1sI8dBl9
4BrTAccR7YfxQuzk0CK5QJPcqLRhvEPOQ/sCQQDYcgaGnzTMlI7LnyQMqctmMcfC
aaJ+ZVJ7QqVfBPMRSgKpSgVYMmqHTfIZWlkxZKOoRcGVEk0WOrV2Jce9Fl+hAkEA
ryob+mQVCd2A0Ad3AymLJh0Loc/U7uW6rXDNp3gVJgypTqMklogEhvvu57i2xWYT
wntaDsH435yyaQWWJacD7wJAQ8ShSWEWThuS+OgRh9j/UpFzXi5MKolQdnWefYCd
2QZRir4eF27Y0TaRr4YvDSddmHW+yGa0Uy2xcWooSSUQSQ==
-----END RSA PRIVATE KEY-----
-----BEGIN PUBLIC KEY-----
MIGJAoGBAMWCSXBIIoIh2gyg9tGtL+RgCUd9urpLKMHH7qu9Dya4YQG236dLBBAS
w9EbIh979s38TSWHWI42qE7fPWqJCg4ZzWYCWrf9Kjx1c7HcdZMbKFu8pmI7+y4a
yMDH84iuZ5oe7Kkwrm5jZNfHQIjZriHcnJD9f1bN8JlGze5mEBvrAgMBAAE=
-----END PUBLIC KEY-----
4、加载现有的RSA密钥文件进行加密解密
func f5() {// load public.pempf, err := os.Open("public.pem")if err != nil {log.Fatal(err)}pfc, err := io.ReadAll(pf)if err != nil {log.Fatal(err)}block, _ := pem.Decode(pfc)if block == nil {log.Fatal("pem decode fail.")}rsaPublicKey, err := x509.ParsePKCS1PublicKey(block.Bytes)if err != nil {log.Fatal(err)}// load private.pempvf, err := os.Open("private.pem")if err != nil {log.Fatal(err)}pvfc, err := io.ReadAll(pvf)if err != nil {log.Fatal(err)}blockv, _ := pem.Decode(pvfc)if block == nil {log.Fatal("pem decode fail.")}rsaPrivateKey, err := x509.ParsePKCS1PrivateKey(blockv.Bytes)if err != nil {log.Fatal(err)}// teststr := "raoxiaoya"encdata, err := rsa.EncryptPKCS1v15(rand.Reader, rsaPublicKey, []byte(str))if err != nil {log.Fatal(err)}log.Println(hex.EncodeToString(encdata))decdata, err := rsa.DecryptPKCS1v15(nil, rsaPrivateKey, encdata)if err != nil {log.Fatal(err)}log.Println(string(decdata))
}
5、使用openssl程序生成RSA公钥密钥
openssl genrsa -out rsa_private_key.pem 1024openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem