• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    Go语言 如何实现RSA加密解密

    RSA是一种非对称加密算法,它的名字是由它的三位开发者,即RonRivest、AdiShamir和LeonardAdleman 的姓氏的首字母组成的(Rivest-Shamir-Adleman ),可用于数据加密和数字签名。

    用于数据加密时,消息发送方利用对方的公钥进行加密,消息接受方收到密文时使用自己的私钥进行解密。

    实现代码如下:

    import (
    	"crypto/rsa"
    	"crypto/rand"
    	"crypto/x509"
    	"os"
    	"encoding/pem"
    	"fmt"
    )
    //生成RSA私钥和公钥,保存到文件中
    func GenerateRSAKey(bits int){
    	//GenerateKey函数使用随机数据生成器random生成一对具有指定字位数的RSA密钥
    	//Reader是一个全局、共享的密码用强随机数生成器
    	privateKey, err := rsa.GenerateKey(rand.Reader, bits)
    	if err!=nil{
    		panic(err)
    	}
    	//保存私钥
    	//通过x509标准将得到的ras私钥序列化为ASN.1 的 DER编码字符串
    	X509PrivateKey := x509.MarshalPKCS1PrivateKey(privateKey)
    	//使用pem格式对x509输出的内容进行编码
    	//创建文件保存私钥
    	privateFile, err := os.Create("private.pem")
    	if err!=nil{
    		panic(err)
    	}
    	defer privateFile.Close()
    	//构建一个pem.Block结构体对象
    	privateBlock:= pem.Block{Type: "RSA Private Key",Bytes:X509PrivateKey}
    	//将数据保存到文件
    	pem.Encode(privateFile,privateBlock)
    	//保存公钥
    	//获取公钥的数据
    	publicKey:=privateKey.PublicKey
    	//X509对公钥编码
    	X509PublicKey,err:=x509.MarshalPKIXPublicKey(publicKey)
    	if err!=nil{
    		panic(err)
    	}
    	//pem格式编码
    	//创建用于保存公钥的文件
    	publicFile, err := os.Create("public.pem")
    	if err!=nil{
    		panic(err)
    	}
    	defer publicFile.Close()
    	//创建一个pem.Block结构体对象
    	publicBlock:= pem.Block{Type: "RSA Public Key",Bytes:X509PublicKey}
    	//保存到文件
    	pem.Encode(publicFile,publicBlock)
    }
    //RSA加密
    func RSA_Encrypt(plainText []byte,path string)[]byte{
    	//打开文件
    	file,err:=os.Open(path)
    	if err!=nil{
    		panic(err)
    	}
    	defer file.Close()
    	//读取文件的内容
    	info, _ := file.Stat()
    	buf:=make([]byte,info.Size())
    	file.Read(buf)
    	//pem解码
    	block, _ := pem.Decode(buf)
    	//x509解码
    	publicKeyInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
    	if err!=nil{
    		panic(err)
    	}
    	//类型断言
    	publicKey:=publicKeyInterface.(*rsa.PublicKey)
    	//对明文进行加密
    	cipherText, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey, plainText)
    	if err!=nil{
    		panic(err)
    	}
    	//返回密文
    	return cipherText
    }
    //RSA解密
    func RSA_Decrypt(cipherText []byte,path string) []byte{
    	//打开文件
    	file,err:=os.Open(path)
    	if err!=nil{
    		panic(err)
    	}
    	defer file.Close()
    	//获取文件内容
    	info, _ := file.Stat()
    	buf:=make([]byte,info.Size())
    	file.Read(buf)
    	//pem解码
    	block, _ := pem.Decode(buf)
    	//X509解码
    	privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
    	if err!=nil{
    		panic(err)
    	}
    	//对密文进行解密
    	plainText,_:=rsa.DecryptPKCS1v15(rand.Reader,privateKey,cipherText)
    	//返回明文
    	return plainText
    }
    

    测试代码如下:

    func main(){
     //生成密钥对,保存到文件
     GenerateRSAKey(2048)
     message:=[]byte("hello world")
     //加密
     cipherText:=RSA_Encrypt(message,"public.pem")
     fmt.Println("加密后为:",string(cipherText))
     //解密
     plainText := RSA_Decrypt(cipherText, "private.pem")
     fmt.Println("解密后为:",string(plainText))
    }

    测试结果如下:

    补充:golang中关于RSA加密、解密、签名、验签的总结

    golang中关于RSA的加密、解密、签名、验签的使用主要在于使用x509及rsa package下相关的方法。

    gocrypt是本人对一般常用的加/解密、签名/验签、hash的封装库,欢迎大家使用。

    以下总结相关的各种变化类型:

    1.秘钥、加密/签名字符串加密的格式

    目前主要见到有hex及base64

    (1)hex

    针对hex的加解密

    hex.DecodeString(s string)//解密
    hex.EncodeToString(src []byte) string//加密

    (2)base64

    base64.StdEncoding.DecodeString(s string) ([]byte, error)//解密
    base64.StdEncoding.EncodeToString(src []byte) string//加密

    2.私钥的格式

    解析私钥的方式如下:

    (1)PKCS1

    x509.ParsePKCS1PrivateKey(der []byte) (key interface{}, err error)

    (2)PKCS8

    x509.ParsePKCS8PrivateKey(der []byte) (key interface{}, err error)

    3.采用的数字签名算法SHA

    以下为RSA sign的不同说明:

    (1)SHA1

        hash := sha1.New()
     hash.Write([]byte(originalData))
     encryptedData, err := rsa.SignPKCS1v15(rand.Reader, prvKey, crypto.SHA1, hash.Sum(nil))

    (2)SHA256

        hash := sha256.New()
     hash.Write([]byte(originalData))
     encryptedData, err := rsa.SignPKCS1v15(rand.Reader, prvKey, crypto.SHA256, hash.Sum(nil))

    4.RSA使用类型

    主要有加密/解密、签名/验签4种方式,且加密/解密与签名/验签均是一个相反的过程。两对是根据对公钥及私钥的使用划分的。

    加密/解密是采用公钥加密,私钥解密。

    签名/验签是采用私钥签名,公钥验签。

    (1)加密

    rsa.EncryptPKCS1v15(rand io.Reader, pub *PublicKey, msg []byte) ([]byte, error)

    (2)解密

    rsa.DecryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) ([]byte, error)

    (3)签名

    rsa.SignPKCS1v15(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []byte) ([]byte, error)

    (4)验签

    rsa.VerifyPKCS1v15(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte) error

    5.具体的使用示例

    (1)加密:采用sha1算法加密后转base64格式
    func RsaEncryptWithSha1Base64(originalData,publicKey string)(string,error){
       key, _ := base64.StdEncoding.DecodeString(publicKey)
       pubKey, _ := x509.ParsePKIXPublicKey(key)
       encryptedData,err:=rsa.EncryptPKCS1v15(rand.Reader, pubKey.(*rsa.PublicKey), []byte(originalData))
       return base64.StdEncoding.EncodeToString(encryptedData),err
    }
    (2)解密:对采用sha1算法加密后转base64格式的数据进行解密(私钥PKCS1格式)
    func RsaDecryptWithSha1Base64(encryptedData,privateKey string)(string,error){
       encryptedDecodeBytes,err:=base64.StdEncoding.DecodeString(encryptedData)
       if err!=nil {
          return "",err
       }
       key,_:=base64.StdEncoding.DecodeString(privateKey)
       prvKey,_:=x509.ParsePKCS1PrivateKey(key)
       originalData,err:=rsa.DecryptPKCS1v15(rand.Reader,prvKey,encryptedDecodeBytes)
       return string(originalData),err
    }
    (3)签名:采用sha1算法进行签名并输出为hex格式(私钥PKCS8格式)
    func RsaSignWithSha1Hex(data string, prvKey string) (string, error) {
       keyByts, err := hex.DecodeString(prvKey)
       if err != nil {
          fmt.Println(err)
          return "", err
       }
       privateKey, err := x509.ParsePKCS8PrivateKey(keyByts)
       if err != nil {
          fmt.Println("ParsePKCS8PrivateKey err", err)
          return "", err
       }
       h := sha1.New()
       h.Write([]byte([]byte(data)))
       hash := h.Sum(nil)
       signature, err := rsa.SignPKCS1v15(rand.Reader, privateKey.(*rsa.PrivateKey), crypto.SHA1, hash[:])
       if err != nil {
          fmt.Printf("Error from signing: %s\n", err)
          return "", err
       }
       out := hex.EncodeToString(signature)
       return out, nil
    }
    (4)验签:对采用sha1算法进行签名后转base64格式的数据进行验签
    func RsaVerySignWithSha1Base64(originalData, signData, pubKey string) error{
       sign, err := base64.StdEncoding.DecodeString(signData)
       if err != nil {
          return err
       }
       public, _ := base64.StdEncoding.DecodeString(pubKey)
       pub, err := x509.ParsePKIXPublicKey(public)
       if err != nil {
          return err
       }
       hash := sha1.New()
       hash.Write([]byte(originalData))
       return rsa.VerifyPKCS1v15(pub.(*rsa.PublicKey), crypto.SHA1, hash.Sum(nil), sign)
    }
    

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。如有错误或未考虑完全的地方,望不吝赐教。

    您可能感兴趣的文章:
    • go 实现简易端口扫描的示例
    • go xorm框架的使用
    • 解析Go的Waitgroup和锁的问题
    • Go语言快速入门图文教程
    • go语言基础 seek光标位置os包的使用
    • Go语言获取文件的名称、前缀、后缀
    • Go 自定义package包设置与导入操作
    • 详解Gotorch多机定时任务管理系统
    上一篇:golang 如何实现HTTP代理和反向代理
    下一篇:Go语言获取文件的名称、前缀、后缀
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    Go语言 如何实现RSA加密解密 语言,如何,实现,RSA,加密解密,