参考:https://blog.csdn.net/lady_killer9/article/details/118026802
1.加密解密工具类PasswordUtil.go
Go
package util
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"fmt"
"log"
"os"
"runtime"
)
// RSA 加密解密
//生成密钥对
func GenerateRsaKey(keySize int, dirPath string) error {
privateKey,err := rsa.GenerateKey(rand.Reader,keySize)
if err != nil{
_, file, line, _ := runtime.Caller(0)
return Error(file,line+1,err.Error())
}
// x509
derText :=x509.MarshalPKCS1PrivateKey(privateKey)
// pem Block
block := &pem.Block{
Type:"rsa private key",
Bytes:derText,
}
// just joint, caller must let dirPath right
file,err := os.Create(dirPath+"private.pem")
defer file.Close()
if err != nil{
_, file, line, _ := runtime.Caller(0)
return Error(file,line+1,err.Error())
}
err = pem.Encode(file,block)
if err != nil{
_, file, line, _ := runtime.Caller(0)
return Error(file,line+1,err.Error())
}
// get PublicKey from privateKey
publicKey := privateKey.PublicKey
derStream,err := x509.MarshalPKIXPublicKey(&publicKey)
if err != nil{
_, file, line, _ := runtime.Caller(0)
return Error(file,line+1,err.Error())
}
block = &pem.Block{
Type:"rsa public key",
Bytes:derStream,
}
file,err = os.Create(dirPath+"public.pem")
if err != nil{
_, file, line, _ := runtime.Caller(0)
return Error(file,line+1,err.Error())
}
err = pem.Encode(file, block)
if err != nil{
_, file, line, _ := runtime.Caller(0)
return Error(file,line+1,err.Error())
}
return nil
}
//加密
func RsaEncrypt(plainText []byte,filePath string) ([]byte, error) {
// get pem.Block
block,err := GetKey(filePath)
if err != nil{
_, file, line, _ := runtime.Caller(0)
return nil,Error(file,line+1,err.Error())
}
// X509
publicInterface,err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil{
_, file, line, _ := runtime.Caller(0)
return nil,Error(file,line+1,err.Error())
}
publicKey,flag := publicInterface.(*rsa.PublicKey)
if flag == false{
_, file, line, _ := runtime.Caller(0)
return nil,Error(file,line+1, "加密发生异常==================="/*errors.RsatransError*/)
log.Println(file)
log.Println(line)
//log.Println("发生异常==============================")
}
// encrypt
cipherText, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey, plainText)
if err != nil{
_, file, line, _ := runtime.Caller(0)
return nil,Error(file,line+1,err.Error())
}
return cipherText,nil
}
//解密
func RsaDecrypt(cipherText []byte,filePath string) (plainText []byte,err error) {
// get pem.Block
block,err := GetKey(filePath)
if err != nil{
_, file, line, _ := runtime.Caller(0)
return nil,Error(file,line+1,err.Error())
}
// get privateKey
privateKey, _ := x509.ParsePKCS1PrivateKey(block.Bytes)
defer func() {
if err2 := recover();err2 != nil{
_, file, line, _ := runtime.Caller(0)
err = Error(file,line,"解密发生异常==================")
}
}()
// get plainText use privateKey
plainText, err3 := rsa.DecryptPKCS1v15(rand.Reader, privateKey, cipherText)
if err3 != nil{
_, file, line, _ := runtime.Caller(0)
return nil,Error(file,line+1,err3.Error())
}
return plainText,err
}
// 读取公钥/私钥文件,获取解码的pem块
// filePath文件路径
// 返回pem块和错误
func GetKey(filePath string) (*pem.Block,error) {
file,err := os.Open(filePath)
defer file.Close()
if err != nil{
_, file, line, _ := runtime.Caller(0)
return nil,Error(file,line+1,err.Error())
}
fileInfo,err := file.Stat()
if err != nil{
_, file, line, _ := runtime.Caller(0)
return nil,Error(file,line+1,err.Error())
}
buf := make([]byte,fileInfo.Size())
_, err = file.Read(buf)
if err != nil{
_, file, line, _ := runtime.Caller(0)
return nil,Error(file,line+1,err.Error())
}
block, _ := pem.Decode(buf)
return block,err
}
// 错误格式化
func Error(file string,line int,err string) error {
return fmt.Errorf("file:%s line:%d error:%s",file,line,err)
}
2.测试
Go
func Rsapassword(c *gin.Context, loginBody *sysEntity.LoginBody) []map[string]interface{} {
var resultList []map[string]interface{}
//参数接收
//userName := loginBody.UserName
//password := loginBody.Password
//生成密钥对
err := sysUtil.GenerateRsaKey(1024, "./")
if err != nil {
log.Println("==================生成密钥对发生异常")
fmt.Println(err)
}
//加密
plainText := []byte("123456")
cipherText, err := sysUtil.RsaEncrypt(plainText, "./public.pem")
if err != nil {
fmt.Println(err)
log.Println("==================加密发生异常")
}
fmt.Printf("加密后为:%s\n",cipherText)
//解密
plainText,err = sysUtil.RsaDecrypt(cipherText,"./private.pem")
if err!=nil{
log.Println("==================解密发生异常")
fmt.Println(err)
}
fmt.Printf("解密后为:%s\n",plainText)
return resultList
}