Golang RSA 生成密钥、加密、解密、签名与验签

文章目录

  • 1.RSA
  • 2.Golang 实现 RSA
    • 生成密钥
    • 加密
    • 解密
    • 签名
    • 验签
  • 3.dablelv/cyan
  • 参考文献

1.RSA

RSA 是最常用的非对称加密算法,由 Ron Rivest、Adi Shamir、Leonard Adleman 于1977 年在麻省理工学院工作时提出,RSA 是三者姓氏首字母的拼接。
在这里插入图片描述
它的基本原理涉及到数学中的大整数因数分解问题,即将一个大的合数(通常是一个极大数字)分解为其素数因子。RSA 算法的安全性基于这个问题的难解性,目前还没有高效的方法可以在合理的时间内分解大整数。

RSA 支持变长密钥非对称加密,需要加密的文件块的长度也是可变的。

2.Golang 实现 RSA

Golang 标准库在 crypto/rsa 包实现了 RSA。

下面将利用 Golang 标准库相演示 RSA 生成密钥、加密、解密、签名与验签等操作。

生成密钥

// GenRsaKey generates an PKCS#1 RSA keypair of the given bit size in PEM format.
func GenRsaKey(bits int) (prvkey, pubkey []byte, err error) {// Generates private key.privateKey, err := rsa.GenerateKey(rand.Reader, bits)if err != nil {return}derStream := x509.MarshalPKCS1PrivateKey(privateKey)block := &pem.Block{Type:  "RSA PRIVATE KEY",Bytes: derStream,}prvkey = pem.EncodeToMemory(block)// Generates public key from private key.publicKey := &privateKey.PublicKeyderPkix, err := x509.MarshalPKIXPublicKey(publicKey)if err != nil {return}block = &pem.Block{Type:  "RSA PUBLIC KEY",Bytes: derPkix,}pubkey = pem.EncodeToMemory(block)return
}

加密

RSA 是一个非对称加密算法,虽然私钥也可以用于加密数据,但因为公钥是对外的,所以加密数据的意义不大,因为知道公钥的所有人都能解密。

所以常见的做法是是用公钥加密数据,私钥解密数据。而私钥则用户签名,公钥用于验签。

// RsaEncrypt encrypts data using rsa public key.
func RsaEncrypt(pubkey, data []byte) ([]byte, error) {block, _ := pem.Decode(pubkey)if block == nil {return nil, errors.New("decode public key error")}pub, err := x509.ParsePKIXPublicKey(block.Bytes)if err != nil {return nil, err}return rsa.EncryptPKCS1v15(rand.Reader, pub.(*rsa.PublicKey), data)
}

解密

// RsaDecrypt decrypts data using rsa private key.
func RsaDecrypt(prvkey, cipher []byte) ([]byte, error) {block, _ := pem.Decode(prvkey)if block == nil {return nil, errors.New("decode private key error")}prv, err := x509.ParsePKCS1PrivateKey(block.Bytes)if err != nil {return nil, err}return rsa.DecryptPKCS1v15(rand.Reader, prv, cipher)
}

签名

// RsaSign signs using private key in PEM format.
func RsaSign(prvkey []byte, hash crypto.Hash, data []byte) ([]byte, error) {block, _ := pem.Decode(prvkey)if block == nil {return nil, errors.New("decode private key error")}privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)if err != nil {return nil, err}// MD5 and SHA1 are not supported as they are not secure.var hashed []byteswitch hash {case crypto.SHA224:h := sha256.Sum224(data)hashed = h[:]case crypto.SHA256:h := sha256.Sum256(data)hashed = h[:]case crypto.SHA384:h := sha512.Sum384(data)hashed = h[:]case crypto.SHA512:h := sha512.Sum512(data)hashed = h[:]}return rsa.SignPKCS1v15(rand.Reader, privateKey, hash, hashed)
}

验签

// RsaVerifySign verifies signature using public key in PEM format.
// A valid signature is indicated by returning a nil error.
func RsaVerifySign(pubkey []byte, hash crypto.Hash, data, sig []byte) error {block, _ := pem.Decode(pubkey)if block == nil {return errors.New("decode public key error")}pub, err := x509.ParsePKIXPublicKey(block.Bytes)if err != nil {return err}// SHA1 and MD5 are not supported as they are not secure.var hashed []byteswitch hash {case crypto.SHA224:h := sha256.Sum224(data)hashed = h[:]case crypto.SHA256:h := sha256.Sum256(data)hashed = h[:]case crypto.SHA384:h := sha512.Sum384(data)hashed = h[:]case crypto.SHA512:h := sha512.Sum512(data)hashed = h[:]}return rsa.VerifyPKCS1v15(pub.(*rsa.PublicKey), hash, hashed, sig)
}

3.dablelv/cyan

以上函数已放置 Golang 实用函数库 dablelv/cyan,欢迎大家 import 使用。

package mainimport (stdcrypto "crypto""fmt""github.com/dablelv/cyan/crypto"
)func main() {prvkey, pubkey, err := crypto.GenRsaKey(2048)if err != nil {panic(err)}data := []byte("foo")// Encrypt data.cipher, err := crypto.RsaEncrypt(pubkey, data)if err != nil {panic(err)}if len(cipher) != 2048/8 {panic("cipher len not equal to key length")}// Decrypt data.plain, err := crypto.RsaDecrypt(prvkey, cipher)if err != nil {panic(err)}if string(data) == string(plain) {fmt.Printf("rsa encrypt and decrypt succeeded, data:%v plain:%v\n", string(data), string(plain))}// Using SHA256 to hash msg and then use rsa private key to sign.sig, err := crypto.RsaSign(prvkey, stdcrypto.SHA256, data)if err != nil {panic(err)}if len(sig) != 2048/8 {panic("signature len not equal to key length")}// Using public key to verify signature.err = crypto.RsaVerifySign(pubkey, stdcrypto.SHA256, data, sig)if err != nil {panic(err)}fmt.Println("verify signature succeeded")
}

运行输出:

rsa encrypt and decrypt succeeded, data:foo plain:foo
verify signature succeeded

参考文献

rsa.com
一文读懂 HTTPS 背后的加密知识

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/124973.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微服务01-基本介绍+注册中心EureKa

基本介绍 服务集群:一个请求由多个服务完成,服务接口暴露,以便于相互调用; 注册中心:每个服务的状态,需要进行维护,我们可以在注册中心进行监控维护服务; 配置中心:这些…

失效的访问控制漏洞复现(dvwa)

文章目录 失效访问控制是什么?dvwa漏洞复现用未授权访问获取shell 代码审计 失效访问控制是什么? 由于缺乏自动化的检测和应用程序开发人员缺乏有效 的功能测试,因而访问控制缺陷很常见。导致攻击者可以冒充用户、管理员或拥有特权的用户&…

Android 10.0 禁用adb shell input输入功能

1.前言 在10.0的产品开发中,在进行一些定制开发中,对于一些adb shell功能需要通过属性来控制禁止使用input 等输入功能,比如adb shell input keyevent 响应输入事件等,所以就需要 熟悉adb shell input的输入事件流程,然后来禁用adb shell input的输入事件功能,接下来分…

GPT-人工智能如何改变我们的编码方式

在本文中,您将找到我对人工智能和工作的最新研究的总结(探索人工智能对生产力的影响,同时开启对长期影响的讨论),一个准实验方法的示例(通过 ChatGPT 和 Stack Overflow 进行说明,了解如何使用简…

python in excel 如何尝鲜 有手就行

众所周知,微软在8月下旬放出消息python已入驻excel,可到底怎么实现呢。 今天我就将发布python in excel的保姆级教程,开始吧! 获取office 365 账号 首先我们要有微软office365 这时候需要再万能的某宝去找一个账号,…

已经2023年了,你还不会手撕轮播图?

目录 一、前言二、动画基础1. 定时器2. left与offsetLeft3. 封装函数3.1 物体3.2 目标点3.3 回调函数 4.封装 三、基础结构3.1 焦点图3.2 按钮3.3 小圆点3.4 总结 四、按钮显示五、圆点5.1 生成5.2 属性5.3 移动 六、按钮6.1 准备6.2 出错6.2.1 小圆点跟随6.2.2 图片返回 6.3 b…

云端AI:释放企业创新力,打造智慧企业

文章目录 1. 云端AI的基本概念1.1 云计算1.2 人工智能1.3 云端AI 2. 云端AI的重要性2.1 成本效益2.2 弹性扩展2.3 无缝整合2.4 实时更新 3. 云端AI的应用领域3.1 智能客服3.2 预测分析3.3 自动化生产 4. 云端AI的未来趋势4.1 边缘计算与云端AI的融合4.2 可解释性AI4.3 隐私和安…

zabbix使用 -- 添加监控节点、自定义监控项、触发器

目录 页面中的一些概念配置agent服务来获取目标主机数据对nginx服务器进行监控在网页中添加一台配置 自定义监控项 -- 以监控nginx为例1、开启nginx本身的统计功能2、编写脚本采集数据3、在zabbix-server里获取数据监控ssh进程监控cron进程 触发器报警1、注册一个企业微信2、微…

开启全新教学模式!vLive虚拟直播如何赋能线上教培

 如今,教培领域正在经历一场数字化的变革。随着科技的迅猛发展,教培形式也在不断演变,越来越多的企业和讲师开始采用虚拟直播来进行在线教学。那么,vLive虚拟直播https://live.vsochina.com/cnvLive虚拟直播是如何赋…

SpringBoot运维实用篇、打包、运行、高级配置、多环境开发、日志

文章目录 SpringBoot运维实用篇YW-1.SpringBoot程序的打包与运行程序打包程序运行SpringBoot程序打包失败处理命令行启动常见问题及解决方案SpringBoot项目快速启动(Linux版) YW-2.配置高级YW-2-1.临时属性设置YW-2-2.配置文件分类YW-2-3.自定义配置文件…

elasticsearch的数据聚合

聚合可以让我们极其方便的实现对数据的统计、分析、运算。例如: 什么品牌的手机最受欢迎? 这些手机的平均价格、最高价格、最低价格? 这些手机每月的销售情况如何? 实现这些统计功能的比数据库的sql要方便的多,而且…

下载安装包,安装 PySide2 到 windows 系统

20201206 修订:修改 PyCharm 中工具的配置描述 一、下载两个.whl 文件到本地, 可以在此下载 https://mirrors.tuna.tsinghua.edu.cn/ 我选用的是以下两个版本: shiboken2-5.15.2-5.15.2-cp35.cp36.cp37.cp38.cp39-none-win_amd64.whl …

vue three.js基本案例解析

1.安装依赖 // 比如安装148版本 npm install three0.148.0 --save2.使用页面引用 import * as THREE from three; // 引入扩展库OrbitControls.js import { OrbitControls } from three/addons/controls/OrbitControls.js; // 引入扩展库GLTFLoader.js import { GLTFLoader }…

攻防世界-WEB-NewsCenter

打开环境 有查询,猜测是sql注入 保存请求头到文件中 准备利用sqlmap 查找数据库 python sqlmap.py -r ./123.txt --dbs 查找表 python sqlmap.py -r ./123.txt --tables -D news 查找字段 python sqlmap.py -r ./123.txt --column -D news -T secret_table 显示字…

Spring整合tomcat的WebSocket详细逻辑(图解)

主要解决存在的疑问 为什么存在2种spring整合websocket的方式,一种是使用ServerEndpoint注解的方式,一种是使用EnableWebSocket注解的方式,这2种有什么区别和联系?可以共存吗?它们实现的原理是什么?它们的各…

华为数通方向HCIP-DataCom H12-821题库(单选题:321-340)

第321题 BGP的Open报文是用于建立对等体连接的,以下哪一项不属于Open报文中携带的参数信息? A、发送者的Router ID B、AS号 C、BGP版本号 D、TCP端口号 答案:D 解析:以下是BGP的Open报文: 第322题 在建立BGP对等体的过程中,OpenSent状态表明BGP等待的Open报文 并对收…

【Java基础篇 | 面向对象】—— 封装详解

个人主页:兜里有颗棉花糖 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 兜里有颗棉花糖 原创 收录于专栏【JavaSE_primary】 本专栏旨在分享学习Java的一点学习心得,欢迎大家在评论区讨论💌 目录 一、封装1.1什么是封装…

thinkphp6 入门(4)--数据库操作 增删改查

一、设计数据库表 比如我新建了一个数据库表,名为test 二、配置数据库连接信息 本地测试 直接在.env中修改,不用去config/database.php中修改 正式环境 三、增删改查 引入Db库 use think\facade\Db; 假设新增的控制器路径为 app\test\control…

【操作系统】聊聊Linux内存工作机制

内存主要是用来存储系统和应用程序的指令、数据、缓存等 内存映射 内存是需要安全机制保护的,所以只有内核才可以直接访问物理内存。进程如果要访问内存需要通过独立的虚拟地址空间。 虚拟地址空间其实包含两部分。一部分是内核空间,另一部分就是用户…

[C++网络协议] I/O复用

具有代表性的并发服务器端实现模型和方法: 多进程服务器:通过创建多个进程提供服务。 多路复用服务器:通过捆绑并统一管理I/O对象提供服务。✔ 多线程服务器:通过生成与客户端等量的线程提供服务。 目录 1. I/O复用 2. select函…