1. 生成公钥和私钥

package mainimport ("crypto/rand""crypto/rsa""crypto/x509""encoding/pem""fmt""os"
)type Rsa struct {}/** 生成RSA公钥和私钥并保存在对应的目录文件下* 参数bits: 指定生成的秘钥的长度, 单位: bit*/
func (r *Rsa) RsaGenKey(bits int, privatePath, pubulicPath string) error {// 1. 生成私钥文件// GenerateKey函数使用随机数据生成器random生成一对具有指定字位数的RSA密钥privateKey, err := rsa.GenerateKey(rand.Reader, bits)if err != nil {return err}// 2. MarshalPKCS1PrivateKey将rsa私钥序列化为ASN.1 PKCS#1 DER编码derPrivateStream := x509.MarshalPKCS1PrivateKey(privateKey)// 3. Block代表PEM编码的结构, 对其进行设置block := pem.Block{Type:  "RSA PRIVATE KEY",Bytes: derPrivateStream,}// 4. 创建文件privateFile, err := os.Create(privatePath)defer privateFile.Close()if err != nil {return err}// 5. 使用pem编码, 并将数据写入文件中err = pem.Encode(privateFile, &block)if err != nil {return err}// 1. 生成公钥文件publicKey := privateKey.PublicKeyderPublicStream, err := x509.MarshalPKIXPublicKey(&publicKey)if err != nil {return err}block = pem.Block{Type:  "RSA PUBLIC KEY",Bytes: derPublicStream,}publicFile, err := os.Create(pubulicPath)defer publicFile.Close()if err != nil {return err}// 2. 编码公钥, 写入文件err = pem.Encode(publicFile, &block)if err != nil {panic(err)return err}return nil
}func (r *Rsa) testGenRSA()  {r.RsaGenKey(2048, "privateKey.pem","publicKey.pem")
}func main() {r := &Rsa{}r.testGenRSA()fmt.Println("成功生成公钥和私钥")
}

2. 数据通信

公钥加密, 私钥解密

package mainimport ("crypto/rand""crypto/rsa""crypto/x509""encoding/pem""fmt""os"
)type Rsa struct {}/** RSA公钥加密*/
func (r *Rsa) RSAEncrypt(src []byte, filename string) ([]byte, error)  {// 根据文件名读出文件内容file, err := os.Open(filename)if err != nil {return nil, err}defer file.Close()info, _ := file.Stat()buf := make([]byte, info.Size())file.Read(buf)// 从数据中找出pem格式的块block, _ := pem.Decode(buf)if block == nil {return nil, err}// 解析一个der编码的公钥pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)if err != nil {fmt.Println(err)return nil, err}publicKey := pubInterface.(*rsa.PublicKey)// 公钥加密result, _ := rsa.EncryptPKCS1v15(rand.Reader, publicKey, src)return result, nil}/** RSA私钥解密*/
func (r *Rsa) RSADecrypt(src []byte, filename string) ([]byte, error) {// 根据文件名读出内容file, err := os.Open(filename)if err != nil {return nil,err}defer file.Close()info, _ := file.Stat()buf := make([]byte, info.Size())file.Read(buf)// 从数据中解析出pem块block, _ := pem.Decode(buf)if block == nil {return nil,err}// 解析出一个der编码的私钥privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)// 私钥解密result, err := rsa.DecryptPKCS1v15(rand.Reader, privateKey, src)if err != nil {return nil,err}return result,nil
}func (r *Rsa) testRSA()  {msg := "This is a girl."cipherText, _:= r.RSAEncrypt([]byte(msg), "publicKey.pem")fmt.Println("加密后的字符串:", string(cipherText))plainText, _:= r.RSADecrypt(cipherText, "privateKey.pem")fmt.Println("解密后的字符串:", string(plainText))
}func main() {r := &Rsa{}r.testRSA()
}

3. 数字签名

私钥加密, 公钥解密

package mainimport ("crypto""crypto/rand""crypto/rsa""crypto/sha512""crypto/x509""encoding/pem""fmt""os"
)func main() {src := []byte("在消息认证码中,需要发送者和接收者之间共享密钥,而这个密钥不能被主动攻击者Mallory获取。如果这个密钥落入Mallory手中,则Mallory也可以计算出MAC值,从而就能够自由地进行篡改和伪装攻击,这样一来消息认证码就无法发挥作用了。")sigText := SignatureRSA(src, "privateKey.pem")bl := VerifyRSA(src, sigText, "publicKey.pem")fmt.Println("数字签名验证结果:", bl)
}// RSA签名 - 私钥
func SignatureRSA(plainText []byte, fileName string) []byte{//1. 打开磁盘的私钥文件file, err := os.Open(fileName)if err != nil {panic(err)}//2. 将私钥文件中的内容读出info, err := file.Stat()if err != nil {panic(err)}buf := make([]byte, info.Size())file.Read(buf)file.Close()//3. 使用pem对数据解码, 得到了pem.Block结构体变量block, _ := pem.Decode(buf)//4. x509将数据解析成私钥结构体 -> 得到了私钥privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)if err != nil {panic(err)}//5. 创建一个哈希对象 -> md5/sha1 -> sha512// sha512.Sum512()myhash := sha512.New()//6. 给哈希对象添加数据myhash.Write(plainText)//7. 计算哈希值hashText := myhash.Sum(nil)//8. 使用rsa中的函数对散列值签名sigText, err := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA512, hashText)if err != nil {panic(err)}return sigText
}
// RSA签名验证
func VerifyRSA(plainText, sigText []byte, pubFileName string) bool {//1. 打开公钥文件, 将文件内容读出 - []bytefile, err := os.Open(pubFileName)if err != nil {panic(err)}info, err := file.Stat()if err != nil {panic(err)}buf := make([]byte, info.Size())file.Read(buf)file.Close()//2. 使用pem解码 -> 得到pem.Block结构体变量block, _ := pem.Decode(buf)//3. 使用x509对pem.Block中的Bytes变量中的数据进行解析 ->  得到一接口pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)if err != nil {panic(err)}//4. 进行类型断言 -> 得到了公钥结构体publicKey := pubInterface.(*rsa.PublicKey)//5. 对原始消息进行哈希运算(和签名使用的哈希算法一致) -> 散列值hashText := sha512.Sum512(plainText)//6. 签名认证 - rsa中的函数err = rsa.VerifyPKCS1v15(publicKey, crypto.SHA512, hashText[:], sigText)if err == nil {return true}return false
}

4. 参考教程

[1] https://blog.csdn.net/boss2967/article/details/83018039
[2] https://www.jianshu.com/p/60fe90594583

【Golang】基于RSA算法的数据通信和数字签名相关推荐

  1. 一个基于RSA算法的Java数字签名例子

    ====================================================== 注:本文源代码点此下载 ================================= ...

  2. 基于RSA算法实现软件注册码原理初讨

    https://blog.csdn.net/larryliuqing/article/details/7457200 前言 目前,商用软件和共享软件绝大部份都是采用注册码授权的方式来保证软件本身不被盗 ...

  3. 基于RSA公匙--PGP邮件数字签名

    PGP (Pretty Good Privacy) 是一个基于RSA公匙加密体系的邮件加密软件.可以用它对邮件保密以防止非授权者阅读,它还能对邮件加上数字签名从而使收信人可以确认邮件的发送者,并能确信 ...

  4. golang通过RSA算法生成token,go从配置文件中注入密钥文件,go从文件中读取密钥文件,go RSA算法下token生成与解析;go java token共用

    RSA算法 token生成与解析 本文演示两种方式,一种是把密钥文件放在配置文件中,一种是把密钥文件本身放入项目或者容器中. 下面两种的区别在于私钥公钥的初始化, init方法,需要哪种取哪种. 通过 ...

  5. Golang 中 RSA 算法的使用

    golang 生成RSA公钥和私钥文件 https://blog.csdn.net/su_sai/article/details/51204008 [Golang软件推荐] RSA公私钥加解密(解决G ...

  6. 基于DES和RSA算法自动分配密钥的加密聊天程序

    文章目录 实现的功能 一.安全加密模型 二.代码 三.运行结果 总结 实现的功能 (1)实现基于DES和RSA算法的自动分配密钥加密聊天程序. (2)实现密钥自动生成,并基于RSA算法进行密钥共享. ...

  7. 【工具编写】python实现非对称加密RSA算法

    python实现非对称加密RSA算法 0x01 RSA算法介绍 RSA加密算法是一种非对称加密算法.在公开密钥加密和电子商业中RSA被广泛使用.RSA是1977年由罗纳德·李维斯特(Ron Rives ...

  8. 非对称加密之RSA算法

    非对称加密之RSA算法 1. RSA算法简述 2. 模型分析 3.代码实现 3.1 算法实现 3.2 测试代码 3.3 测试结果 4. 算法实现分析 5. 数据分段处理 该系列文章列表 1.网络及数据 ...

  9. SM2算法对比RSA算法,有哪些优势?

    SM2算法和RSA算法都是公钥密码算法,SM2算法是一种更先进安全的算法,在安全性能.速度性能等方面都优于RSA算法,在我国商用密码体系中被用来替换RSA算法.国家密码管理局于2010年12月17日发 ...

  10. RSA 算法工具类(纯JDK,无引入jar)

    下面是RSA 生成公私钥 加解密 加签验签的功能类 开放平台签名算法名称 标准签名算法名称 备注 RSA2 SHA256WithRSA 强制要求 RSA 密钥的长度至少为 2048 RSA SHA1W ...

最新文章

  1. 微软推出MSDN2008中文版有些仓促,中文的MSDN2008Beta2内容都是E文的...
  2. Response_输出数据,实现文件下载,定时刷新页面,是否缓存,重定向,实现验证码...
  3. OpenCV Laplacian算子
  4. Android图片360全景旋转
  5. php中一定要写 吗,PHP编程一定要改掉的5个不良习惯
  6. centos7设置成文件服务器,CentOS7服务器架设ftp过程
  7. MacOS使用brew无法安装Python_无法安装gdbm_无法安装autojump
  8. PHP之MVC项目实战(二)
  9. [转载] 1.1Java使用JDBC原生方式连接MySql数据库
  10. 生产环境运行Docker的9个关键决策
  11. C#LeetCode刷题之#434-字符串中的单词数​​​​​​​(Number of Segments in a String)
  12. 大数据之-Hadoop3.x_MapReduce_排序概述---大数据之hadoop3.x工作笔记0114
  13. npm换成国内源 npm换源 npm换淘宝源镜像
  14. php案例之后台数据显示-- mysqli面向过程版(procedure oriented programming = POP)
  15. 【优化求解】基于matlab遗传算法求解仓库货位优化问题【含Matlab源码 1770期】
  16. 免费SSL证书的制作
  17. 计算机显示正常 但打印出来乱码,打印出乱码字体怎么办
  18. kubeadm部署1.11.1的k8s集群
  19. 微信服务器系统,微信公众号服务器系统基础组件研发
  20. 打开设备管理器找不到Android Composite ADB Interface

热门文章

  1. Git部署Git使用Git子模块
  2. mysql transaction-isolation_MySQL数据库事务隔离级别(Transaction Isolation Level)
  3. [Golang]解决Map的并发性问题:sync.Map
  4. c#数据库连接总结2上篇(通过数据库进行登入和注册)
  5. linux选择内核命令,Lenky个人站点
  6. suspend java_Java线程stop和suspend的废弃
  7. python多线程执行_一个Python多线程运行实例
  8. python timedelta_Python使用笔记:时间的运算timedelta
  9. html框架设计左侧嵌套,html页面嵌套使用示例(frameset使用方法)
  10. 宕昌一中2021高考成绩查询,2014年陇南市普通高考分数成绩排名