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)

}

posted @ 2023-04-12 16:58  ClassicalRain  阅读(200)  评论(0编辑  收藏  举报