go语言rsa非对称加解密
最近用到rsa非对称加密解密算法,且将密钥、公钥作为应用程序的配置存放在配置文件或数据库中,苦于未找到go语言相关实现,自己东拼西凑简单实现一下;本文未涉及rsa算法的原理,仅仅用go语言实现了一下rsa密钥生成、加密、解密的工具,代码如下
package main
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/base64"
"encoding/json"
"encoding/pem"
"errors"
"fmt"
)
// Rsa生成私钥/公钥
func RsaGenKey(bits int) (privateKey string, publicKey string, err error) {
rsaPrivateKey, err := rsa.GenerateKey(rand.Reader, bits)
if err != nil {
return privateKey, publicKey, err
}
privateKeyBytes := x509.MarshalPKCS1PrivateKey(rsaPrivateKey)
publicKeyBytes, err := x509.MarshalPKIXPublicKey(&rsaPrivateKey.PublicKey)
if err != nil {
return privateKey, publicKey, err
}
privateBlock := &pem.Block{
Type: "private key",
Bytes: privateKeyBytes,
}
publicBlock := &pem.Block{
Type: "public key",
Bytes: publicKeyBytes,
}
// 将私钥/公钥写入内存并base64编码
privateKey = base64.URLEncoding.EncodeToString(pem.EncodeToMemory(privateBlock))
publicKey = base64.URLEncoding.EncodeToString(pem.EncodeToMemory(publicBlock))
return privateKey, publicKey, nil
}
// 公钥加密
func RsaEncrypt(data, publicKey string) (string, error) {
// base64解码
publicKeyBytes, err := base64.URLEncoding.DecodeString(publicKey)
if err != nil {
return data, err
}
publicKeyBlock, _ := pem.Decode(publicKeyBytes)
if publicKeyBlock == nil {
return data, errors.New("pem.Decode public key error")
}
keyInit, err := x509.ParsePKIXPublicKey(publicKeyBlock.Bytes)
if err != nil {
return data, err
}
key := keyInit.(*rsa.PublicKey)
// 数据加密
encryptBytes, err := rsa.EncryptPKCS1v15(rand.Reader, key, []byte(data))
if err != nil {
return data, err
}
// 将加密数据base64编码
return base64.URLEncoding.EncodeToString(encryptBytes), nil
}
// 私钥解密
func RsaDecrypt(data, privateKey string) (string, error) {
// 密钥base64解码
privateKeyBytes, err := base64.URLEncoding.DecodeString(privateKey)
if err != nil {
return data, err
}
privateKeyBlock, _ := pem.Decode(privateKeyBytes)
if privateKeyBlock == nil {
return data, errors.New("pem.Decode private key error")
}
key, err := x509.ParsePKCS1PrivateKey(privateKeyBlock.Bytes)
if err != nil {
return data, err
}
// 将加密数据base64解码
dataBytes, err := base64.URLEncoding.DecodeString(data)
if err != nil {
return data, err
}
// 数据解密
encryptBytes, err := rsa.DecryptPKCS1v15(rand.Reader, key, dataBytes)
if err != nil {
return data, err
}
return string(encryptBytes), nil
}
type User struct {
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
// 获取私钥、密钥
privateKey, publicKey, err := RsaGenKey(1024)
if err != nil {
fmt.Println(err)
}
data := "123abc"
fmt.Println("加密前:", data)
// 公钥加密
data, err = RsaEncrypt(data, publicKey)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("加密后:", data)
// 私钥解密
data, err = RsaDecrypt(data, privateKey)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("解密后:", data)
fmt.Println("=====================")
user1 := &User{
Name: "木讷技术宅小孙",
Age: 18,
}
fmt.Println("user1:", *user1)
// json序列化
userJson, err := json.Marshal(user1)
if err != nil {
fmt.Println(err)
return
}
data = (string)(userJson)
fmt.Println("加密前:", data)
// 公钥加密
data, err = RsaEncrypt(data, publicKey)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("加密后:", data)
// 私钥解密
data, err = RsaDecrypt(data, privateKey)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("解密后:", data)
var user2 User
// json反序列化
json.Unmarshal([]byte(data), &user2)
fmt.Println("user2:", user2)
}