golang中的RSA算法,加密解密,签名校验,导出公钥密钥,导入公钥密钥

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.pem
	pf, 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.pem
	pvf, 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)
	}

	// test
	str := "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 1024

openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem

你可能感兴趣的:(golang,golang,算法,开发语言)