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.mzph.cn/news/71275.shtml

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

相关文章

大数据安全 | (一)介绍

目录 📚大数据安全 🐇大数据安全内涵 🐇大数据安全威胁 🐇保障大数据安全 ⭐️采集环节安全技术 ⭐️存储环节安全技术 ⭐️挖掘环节安全技术 ⭐️发布环节安全技术 🐇大数据用于安全 📚隐私及其…

数据结构day07(栈和队列)

今日任务 链式队列&#xff1a; head.h #ifndef __HEAD_H__ #define __HEAD_H__#include <stdio.h> #include <stdlib.h>typedef int datatype; typedef struct link_list{datatype data;struct link_list* next; }link,*linkp; typedef struct circulate_line_t…

Redis简易入门15招

Redis简易入门15招 1、Redis简介 REmote DIctionary Server(Redis) 是一个由 Salvatore Sanfilippo写的key-value存储系统 。Redis是一个开源的使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库&#xff0c;并提供多种语言的API。…

机车整备场数字孪生 | 图扑智慧铁路

机车整备场是铁路运输系统中的重要组成部分&#xff0c;它承担着机车的维修、保养和整备工作&#xff0c;对保障铁路运输的运维和安全起着至关重要的作用。 随着铁路运输的发展、机车技术的不断进步&#xff0c;以及数字化转型的不断推进&#xff0c;数字孪生技术在机车整备场…

Android性能优化深入解析,将你的APP优化到极致的操作~

作为一个Android程序员&#xff0c;性能优化是无法避开的事情&#xff0c;并且性能优化也是Android中最有挑战的工作之一&#xff0c;更是每个工程师都需要掌握的核心技能。 性能问题和Bug不同&#xff0c;后者的分析和解决思路更清晰&#xff0c;很多时候从应用日志即可直接找…

云原生架构如何助力大数据和AI技术在软件开发中的深度整合

文章目录 1. 云原生架构简介2. 大数据与云原生的融合a. 弹性计算和存储b. 容器化大数据应用c. 数据湖和数据仓库 3. AI与云原生的深度融合a. 弹性AI模型训练b. 容器化AI应用c. 自动化部署和监控 4. 对软件开发的影响a. 更快的开发周期b. 更低的成本c. 更高的灵活性和可伸缩性 5…

Revit SDK 介绍:GenericModelCreation常规模型的创建

前言 这个例子介绍了如何创建拉伸、放样、扫掠、融合、放样融合&#xff0c;涵盖了一个建模软件需要的基本建模方法。 内容 CreateExtrusion 生成的放样融合接口&#xff1a; m_creationFamily.NewExtrusion(true, curve, sketchPlane, bottomProfile, topProfile)核心逻辑&…

【SpringBoot】统一功能处理

目录 &#x1f383;1 拦截器 &#x1f380;1.1 拦截器的代码实现 &#x1f3a8;1.2 拦截器的实现原理 &#x1f9f6;2 拦截器应用——登录验证 &#x1f9ba;3 异常统一处理 &#x1f3ad;4 统一数据返回格式 &#x1f9e4;4.1 为什么需要统一数据返回格式 &#x1f9e3;4.2 统…

手写Spring:第1章-开篇介绍,手写Spring

文章目录 一、手写Spring二、Spring 生命周期 一、手写Spring &#x1f4a1; 目标&#xff1a;我们该对 Spring 学到什么程度&#xff1f;又该怎么学习呢&#xff1f; 手写简化版 Spring 框架&#xff0c;了解 Spring 核心原理&#xff0c;为后续再深入学习 Spring 打下基础。在…

0013Java程序设计-springboot教材图文内容审核系统

摘 要目 录第1章 绪论1.1 研究背景与意义1.2 研究内容1.3 论文组成结构 系统实现用户登录模块的实现后台管理系统登录模块的实现投稿信息的实现 开发环境 摘 要 《教材图文内容审核系统》课程案例库研究系统系统主要功能模块包括投稿信息、打卡记录、新闻资讯等&#xff0c;采…

MySQL加密的几种常见方式

MySQL提供了多种加密方式来保护数据的安全性。下面是几种常见的MySQL加密方式&#xff1a; 密码加密&#xff1a; MySQL5.7及以上版本使用SHA-256算法对密码进行加密。这种加密方式更安全&#xff0c;可以防止密码泄露。 之前的MySQL版本使用SHA-1算法进行密码加密。这种加密方…

Python UI自动化 —— pytest常用运行参数解析、pytest执行顺序解析

pytest常用Console参数&#xff1a; -v 用于显示每个测试函数的执行结果-q 只显示整体测试结果-s 用于显示测试函数中print()函数输出-x 在第一个错误或失败的测试中立即退出-m 只运行带有装饰器配置的测试用例-k 通过表达式运行指定的测试用例-h 帮助 首先来看什么参数都没加…

曾国藩农民出身,弯道超车实现逆袭的大智慧

曾国藩从小就笨笨的&#xff0c;读书多了才开窍&#xff0c;实现人生逆袭。农民出身&#xff0c;弯道超车&#xff0c;贵在坚持。 约翰生说过&#xff1a;“成大事不在于力量的大小&#xff0c;而在于能坚持多久。” 很多家长认为“不让孩子输在起跑线上”&#xff0c;这是错…

文件包含漏洞学习小结

目录 一、介绍 二、常见文件包含函数 三、文件包含漏洞代码举例分析 四、文件包含漏洞利用方式 4.1 本地文件包含 1、读取敏感文件 2、文件包含可运行的php代码 ①包含图片码 ②包含日志文件 ③包含环境变量getshell ④临时文件包含 ⑤伪协议 4.2 远程文件包含 4.…

数据结构与算法学习(day1)——简化版桶排序

文章目录 前言本章目标简化版桶排序题目一题目二 前言 &#xff08;1&#xff09;我是一个大三的学生&#xff08;准确来说应该是准大三&#xff0c;因为明天才报名哈哈哈&#xff09;。 &#xff08;2&#xff09;最近就想每天闲着没事也刷些C语言习题来锻炼下编程水平&#x…

Elasticsearch安装,Springboot整合Elasticsearch详细教程

Elasticsearch 是一个分布式、RESTful 风格的搜索和数据分析引擎&#xff0c;能够实现近乎实时的搜索。 Elasticsearch官网https://www.elastic.co/cn/ 这篇文章主要简单介绍一下Elasticsearch&#xff0c;Elasticsearch的java API博主也在学习中&#xff0c;文章会持续更新~ …

把握市场潮流,溯源一流品质:在抖in新风潮 国货品牌驶过万重山

好原料、好设计、好品质、好服务……这个2023&#xff0c;“国货”二字再度成为服饰行业的发展关键词。以消费热潮为翼&#xff0c;越来越多代表性品类、头部品牌展现出独特价值&#xff0c;迎风而上&#xff0c;在抖音电商掀起一轮轮生意风潮。 一个设问是&#xff1a;在抖音…

无需设计经验,也能制作出精美的房地产电子传单

在数字化时代&#xff0c;传统的纸质传单已经不能满足人们对于互动和个性化的需求。为此&#xff0c;许多房地产公司开始将目光转向H5微传单&#xff0c;这是一种通过互联网和手机浏览器来传达信息的创新方式。今天&#xff0c;我们将教你如何使用乔拓云网制作房地产微传单H5&a…

Web服务器部署上线踩坑流程回顾

5月份时曾部署上线了C的Web服务器&#xff0c;温故而知新&#xff0c;本篇文章梳理总结一下部署流程知识&#xff1b; 最初的解决方案&#xff1a;https://blog.csdn.net/BinBinCome/article/details/129750951?spm1001.2014.3001.5501后来的解决方案&#xff1a;https://blog…

算法通关村第十二关——不简单的字符串转换问题

前言 字符串是我们在日常开发中最常处理的数据&#xff0c;虽然它本身不是一种数据结构&#xff0c;但是由于其可以包含所有信息&#xff0c;所以通常作为数据的一种形式出现&#xff0c;由于不同语言创建和管理字符串的方式也各有差异&#xff0c;因此针对不同语言特征又产生…