RSA加密——go语言版
RSA加密——go语言版
- 源起
- 公钥和私钥格式关系
- 公钥
- 私钥
- go语言生成公私钥
- go加载私钥
- pkcs1
- pkcs8
- go加载公钥
- go进行rsa加密和验签
- openssl生成的公私钥
- 去掉私钥的密码
- openssl公钥和openssh公钥互转
- 参考
源起
在做rsa加密验签的过程中遇到了一些问题,在对整个rsa体系不够了解的情况下花了很多的时间去尝试,但总是各种不通、各种头疼。
在尝试和搜索方案的过程中,不断的发现原来平时对rsa的了解是如此的少,rsa的体系是如此的庞大和庞杂。
不知道大家对rsa的了解程度如何,作为一个几年经验的后端程序员来说,对加密的大致体系有所了解,知道简单异或、md5、对称、非对称、用过几种对称加密算法。非对称加密在做支付对接的时候也有所接触。对rsa加密的原理有所了解,知道如何配置ssh免密、如何配置git的ssh、如何配置nginx的单向、双向ssl证书。
然而,这些只是外围知识而已!!!
当然,由于不是密码学专业,也不是安全方向,这里不对非对称加密的体系和算法进行分析,我个人也没有去学习和分析。这里仅包含在处理问题和后续梳理过程中涉及的知识要点。
公钥和私钥格式关系
这个格式关系很重要。对于理解秘钥加载的步骤,对于拿到手上的各种样式的秘钥的理解能有一个心理准备,有一个总体的可能性判断。
公钥
一般来说,我们遇到的公钥是PEM格式,PEM格式是对DER格式公钥的一种封装,封装的内容包括以下几块:
块名称 | 块内容示例 |
---|---|
头 | -----BEGIN PUBLIC KEY----- |
公钥 | base64.encode(public_key_string) |
尾 | -----END PUBLIC KEY----- |
以下是一个PEM格式公钥的示例:
-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEA+xGZ/wcz9ugFpP07Nspo6U17l0YhFiFpxxU4pTk3Lifz9R3zsIsu
ERwta7+fWIfxOo208ett/jhskiVodSEt3QBGh4XBipyWopKwZ93HHaDVZAALi/2A
+xTBtWdEo7XGUujKDvC2/aZKukfjpOiUI8AhLAfjmlcD/UZ1QPh0mHsglRNCmpCw
mwSXA9VNmhz+PiB+Dml4WWnKW/VHo2ujTXxq7+efMU4H2fny3Se3KYOsFPFGZ1TN
QSYlFuShWrHPtiLmUdPoP6CV2mML1tk+l7DIIqXrQhLUKDACeM5roMx0kLhUWB8P
+0uj1CNlNN4JRZlC7xFfqiMbFRU9Z4N6YwIDAQAB
-----END RSA PUBLIC KEY-----
HEX是十六进制编码格式,用的比较少,以下是一个十六进制格式的公钥示例:
00 00 00 07 73 73 68 2d 72 73 61 00 00 00 01 25 00 00 01 00 7f 9c 09
8e 8d 39 9e cc d5 03 29 8b c4 78 84 5f d9 89 f0 33 df ee 50 6d 5d d0
16 2c 73 cf ed 46 dc 7e 44 68 bb 37 69 54 6e 9e f6 f0 c5 c6 c1 d9 cb
f6 87 78 70 8b 73 93 2f f3 55 d2 d9 13 67 32 70 e6 b5 f3 10 4a f5 c3
96 99 c2 92 d0 0f 05 60 1c 44 41 62 7f ab d6 15 52 06 5b 14 a7 d8 19
a1 90 c6 c1 11 f8 0d 30 fd f5 fc 00 bb a4 ef c9 2d 3f 7d 4a eb d2 dc
42 0c 48 b2 5e eb 37 3c 6c a0 e4 0a 27 f0 88 c4 e1 8c 33 17 33 61 38
84 a0 bb d0 85 aa 45 40 cb 37 14 bf 7a 76 27 4a af f4 1b ad f0 75 59
3e ac df cd fc 48 46 97 7e 06 6f 2d e7 f5 60 1d b1 99 f8 5b 4f d3 97
14 4d c5 5e f8 76 50 f0 5f 37 e7 df 13 b8 a2 6b 24 1f ff 65 d1 fb c8
f8 37 86 d6 df 40 e2 3e d3 90 2c 65 2b 1f 5c b9 5f fa e9 35 93 65 59
6d be 8c 62 31 a9 9b 60 5a 0e e5 4f 2d e6 5f 2e 71 f3 7e 92 8f fe 8b
ssh生成的公钥,有自己的格式,由3部分组成“ssh-rsa”字符+公钥+备注。以下是一个ssh公钥的示例:
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD3O26p3AlNy5JalOon2E2q62fygTBQZkVv4LJP1v7UxMH8pMNbsP1YG2keMotLtakHiqfHDd/s6eUDQYxU2nVdwruwPmP65mfhD0xTXsFFOdn+B80EVQdkm12h9Mcd9pVzMTplvB9v2j/8RX8UH45KsCgB5GcZJwdexJWys64Q+5eP386xZ7ow3XkKDS+XCEQTZaz+vN97aOQontwp+Dj0lB0VKhpnCWI5cadFRCNVitWaLLK6STRrYKV9CTUWOIuIV+2EC85UGIGmD3M+z6S3RZepoOZPDCRgaXdiNNsAAWa2ULZ9Wep9Qtly0NEsQ9EHrmeHadnDaWQy9w/KLsYj 362493050@qq.com
私钥
私钥常遇到的是pkcs1和pkcs8两种标准,有时候还会遇到加密后的私钥,需要用密码加载或者去掉秘钥后再使用。后续会说到格式转换和去掉私钥密码的方法。
go语言生成公私钥
由于不同语言对rsa公私钥支持程度不同,所以很可能遇到在java项目用的很好的秘钥,在go语言没有办法用。但是又不确定是秘钥的问题,还是代码写法的问题。这时候如果能够生成一套所使用语言支持的秘钥对,对解决问题和建立信心都有很大帮助。
func GenRsaKey(bits int) error {// 生成私钥文件privateKey, err := rsa.GenerateKey(rand.Reader, bits)if err != nil {return err}derStream := x509.MarshalPKCS1PrivateKey(privateKey)block := &pem.Block{Type: "RSA PRIVATE KEY",Bytes: derStream,}file, err := os.Create("private.pem")if err != nil {return err}err = pem.Encode(file, block)if err != nil {return err}// 生成公钥文件publicKey := &privateKey.PublicKeyderPkix, err := x509.MarshalPKIXPublicKey(publicKey)if err != nil {return err}block = &pem.Block{Type: "PUBLIC KEY",Bytes: derPkix,}file, err = os.Create("public.pem")if err != nil {return err}err = pem.Encode(file, block)if err != nil {return err}return nil
}
go加载私钥
pkcs1
package mainimport ("fmt""crypto/x509""encoding/pem""crypto/rsa")func main () {privateKey := `your key`blockPri, _ := pem.Decode([]byte(privateKey))if blockPri == nil {fmt.Println("err1")return} priKey, err := x509.ParsePKCS1PrivateKey([]byte(blockPri.Bytes))if err != nil {fmt.Println(err)fmt.Println("err2")return }fmt.Println("ok")fmt.Println(priKey)}
pkcs8
package mainimport ("fmt""crypto/x509""encoding/pem""crypto/rsa")func main () {privateKey := `your key`blockPri, _ := pem.Decode([]byte(privateKey))if blockPri == nil {fmt.Println("err1")return}prkI, err := x509.ParsePKCS8PrivateKey([]byte(blockPri.Bytes))if err != nil {fmt.Println(err)fmt.Println("err2")return }priKey := prkI.(*rsa.PrivateKey)fmt.Println("ok")fmt.Println(priKey)}
go加载公钥
blockPub, _ := pem.Decode([]byte(publicKey))if blockPub == nil {fmt.Println("err1")return}pubKey, err := x509.ParsePKIXPublicKey(publicKey)if err != nil {fmt.Println(err)fmt.Println("err2")return }fmt.Println("ok")fmt.Println(pubKey)
go进行rsa加密和验签
以下是hash摘要方式的rsa加密验签,也可以使用md5摘要方式的rsa加密:
//your_private_key和your_public_key都是上述《go加载rsa公、私钥》部分创建的结构体类型
func Sign(src []byte, hash crypto.Hash) ([]byte, error) {h := hash.New()h.Write(src)hashed := h.Sum(nil)return rsa.SignPKCS1v15(rand.Reader, your_private_key, hash, hashed)
}func Verify(src []byte, sign []byte, hash crypto.Hash) error {h := hash.New()h.Write(src)hashed := h.Sum(nil)return rsa.VerifyPKCS1v15(your_public_key, hash, hashoed, sign)
}
这里说一下为什么要先摘要,再加密和验签,这里主要考虑的是性能,因为用rsa加密方式对性能的损耗比较大,如果待加密字串长的话,加密过程对性能的影响更大。所以,一般会先对字符串进行hash或者md5摘要。
openssl生成的公私钥
//生成私钥,默认生成的是pkcs1格式私钥
genrsa -out rsa_private_key.pem 1024
//转成pkcs8格式
pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM –nocrypt
//生成公钥
rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
去掉私钥的密码
//执行会后,会要求你输入私钥使用的密码
openssl rsa -in my_private_key.pem -out new_private_key.pem
openssl公钥和openssh公钥互转
两者的私钥是同样的格式,但是两者的公钥是不同的格式,所以转换的基础就是私钥。通过私钥生成另一种格式的公钥。
比如,如果已经有了openssl生成的私钥,可以用如下命令生成openssh的公钥:
ssh-keygen -y -f openssh_private.pem > public_key.pub
~~~~~~~~~~~~~~~~~~~~~~~~~ 福利分割线~~~~~~~~~~~~~~~~~~~~~~~~~~~
-长期内推-:头条、快手、美团、阿里、陌陌、当当。有需要的朋友可以发邮件到我的邮箱xiaofan860412@163.com。
参考
本文参考了下列文章,有的代码片段直接取自文章:
- Golang加密系列之RSA
- GO加密解密RSA番外篇:生成RSA密钥
- GO加密解密之RSA
- PKCS标准
- openssl数字证书常见格式与协议介绍
- Generating an SSH Key Pair
- Generate Private key with OpenSSL and Public key ssh-keygen for SSH
- Converting keys between openssl and openssh
- How are the files in ~/.ssh related to the theory?
- OpenSSH RSA Public Key format
- openssl 生成公私钥对
- 去掉ssh key的密码
RSA加密——go语言版相关推荐
- rsa加密c语言源码库,RSA加密算法源代码C语言实现.doc-资源下载在线文库www.lddoc.cn...
RSA加密算法_源代码__C语言实现.doc RSA 算法 1978 年就出现了这种算法,它是第一个既能用于数据加密也能用于数字签名的算法.它易于理解和操作,也很流行.算法的名字以发明者的名字命名Ro ...
- go java rsa_RSA加密——go语言版-Go语言中文社区
源起 在做rsa加密验签的过程中遇到了一些问题,在对整个rsa体系不够了解的情况下花了很多的时间去尝试,但总是各种不通.各种头疼. 在尝试和搜索方案的过程中,不断的发现原来平时对rsa的了解是如此的少 ...
- 电报加密C语言版(字符串整体后移一位的方法)
题目 1042: [编程入门]电报加密 时间限制: 1Sec 内存限制: 128MB 题目描述 输入一行电报文字,将字母变成其下一字母(如'a'变成'b'--'z'变成'a'其它字符不变). 输入格式 ...
- rsa加解密算法报告c语言,RSA加密解密算法c语言程序Word版
<RSA加密解密算法c语言程序Word版>由会员分享,可在线阅读,更多相关<RSA加密解密算法c语言程序Word版(5页珍藏版)>请在人人文库网上搜索. 1.传播优秀Word版 ...
- 跨语言平台的RSA加密、解密、签名、验证算法的实现
在网上可以找到各种各样的RSA实现代码,原理都是RSA算法的基本原理,但是在处理数据块划分.填充等问题上都是形形色色的,本文旨在探讨.实现遵循RFC 2313 PKCS#1 v1.5标准的一种跨语 ...
- php rsa加密实例,关于PHP语言的RSA加密实例讲解
本文主要向大家介绍了关于PHP语言的RSA加密实例讲解,通过具体的内容向大家展示,希望对大家学习php语言有所帮助. 这几天做了一些接口的对接需要用到RSA加密,百度一番发现原来有个openssl_p ...
- MacOS下使用C语言基于openssl库进行RSA加密解密
MacOS下使用C语言基于openssl库进行RSA加密解密 1 安装openssl并生成密钥 首先当然要安装openssl(这里记得看一下安装路径,应该是/usr/local/Cellar/open ...
- GO语言实现RSA 加密和解密的实现
RSA 加密和解密的实现 openssl生成私钥 openssl genrsa -out rsa_private_key.pem 1024 openssl生成公钥 openssl rsa -in rs ...
- 一个简单地C语言程序展示RSA加密原理
#include<stdio.h> #include<stdlib.h> #include<time.h> #include<math.h>//质数判定 ...
最新文章
- 爬虫之lxml模块中etree.tostring函数的使用
- linux定义别名出错,Linux自定义别名alias重启失效问题
- tf.where() 详解
- vim 有用命令-20190217
- One-Stage Visual Grounding论文汇总
- sybase数据库脱机,无法联机问题处理
- linux磁盘管fdisk,Linux 磁盘分区工具和挂载,fdisk管理分区详解
- Java程序员校招蚂蚁金服,大专生出身,做Java程序员真的没有春天吗
- HDU-1069 Monkey and Banana 动态规划
- word课程表设置符号与编号_小学生课程表word模板 小学生使用WORD.doc
- PPT设置自动保存时间 mac_如何让你的PPT变得高大上?
- mini6410 LED驱动程序及LED测试程序的设计
- 超人游戏_将障碍画在背景中用pygame.mask.from_threshold实现超人和不同颜色障碍精准碰撞检测
- 用 regedit 命令把注册表 .reg 文件导入注册表- -
- main flag redefined: graceful
- Excel办公中的应用(中秋快乐学习)(注意:全部为英文符号)
- python start方法_进程方法 run和start的区别
- mysql数据库基操所遇问题及相关知识及命令记录
- iOS系统的各种设备识别码
- Android kotlin run函数学习