openssl中RSA、SM2公私钥生成及PKCS格式转换
工具网站:
Java相关解析代码,可以参考我这个仓库:easy-cryptography
1.背景
本文openssl版本1.1.1
本文基于openssl,也可以看下GmSSL(支持国密SM2/SM3/SM4/SM9/ZUC/SSL的密码工具箱)。
openssl查看版本:
1.1 使用场景
通常来说。
Java 的开发者,将 pkcs8 去除头尾、换行和空格,以加载秘钥。
.NET 和 PHP 的开发者来说,无需进行 pkcs8 命令行操作。
1.2 PKCS#1和PKCS#8
以RSA为例
PKCS#1 和 PKCS#8 是两种用于表示和存储私钥的标准,它们由 RSA 实验室制定,并且被广泛用于各种加密系统中。它们的主要区别在于编码格式和使用场景。
- PKCS#1 (Public Key Cryptography Standards #1) 专门用于描述 RSA 密钥对。它定义了 RSA 私钥和公钥的结构。
- PKCS#8 (Public Key Cryptography Standards #8) 是一种通用的私钥表示标准,它不仅适用于 RSA 密钥,也适用于其他类型的密钥,如 DSA 和 ECC 密钥。
好,你已经有个基本印象了,PKCS#1起初是专门针对RSA设计的,PKCS#8是相对通用的一个标准。
那么,为啥咱们也能把国密的转成PKCS#1格式呢?
PKCS#1 和 PKCS#8 是与 RSA 加密算法相关的标准,而 SM2 是中国国家密码管理局 (OSCCA) 制定的一种基于椭圆曲线密码学 (ECC) 的公钥密码算法,与 RSA 有着不同的数学基础和实现方式。
因此,严格来说,SM2 私钥不应该被直接转换成 PKCS#1 格式。
然而,SM2 私钥可以被编码为与 PKCS#1 类似的格式,主要是因为两者都依赖于 ASN.1 (Abstract Syntax Notation One) 来描述密钥的结构和数据。
在 ASN.1 的帮助下,我们可以定义和描述任意的密码对象结构。因此,通过适当的 ASN.1 描述,我们可以使 SM2 私钥数据看起来像 PKCS#1 格式。
1.2.1 PKCS#1
只是一个 RSA 密钥,即只有PKCS#8 中的密钥对象部分,前面没有版本或算法标识符。
示例:
用ASN1在线解析PKCS1格式的秘钥,可以看到结果就是一堆数字。
1.2.2 PKCS#8
补充了一些相关信息,不单单只是秘钥值。其实这里可以看到,开头的RSA字眼已经消失了,因为我们能从OID中查看到(后方有图)。
示例:
用ASN1在线解析PKCS8格式的秘钥,可以看到结果在数值之上,追加了OID等信息。
1.2.3 区分PKCS#1和PKCS#8?
PKCS#1格式是比较简洁的,所以头部需要BEGIN RSA PRIVATE KEY
这种声明,你看,出现了RSA的字样。
以SM2举例下,头部是出现了SM2字样的,有头部的说明信息来标识密钥类型。
而PKCS#8时,SM2、RSA这部分字段已经消失了。
1.3 pem和der
PEM 与 DER是用于存储、传输密钥和证书的标准格式,两者紧密关联,可以互相转换。
PEM 和 DER 的主要区别在于它们的编码方式
- DER: 二进制格式,ASN.1结构的直接编码,更紧凑。后缀通常为
.der
和.cer
。 - PEM: 使用 Base64 编码,可读性更好,但文件大小更大。后缀通常为
.pem
、.cer
、.crt
、.key
1.3.1 PEM 转 DER
- 先将 PEM 文件里面首尾的
----BEGIN xxx----
和----END xxx----
两行去掉 - 再将内容合并为一行(去掉换行符
\r\n
) - 接着将内容进行 Base64 解码得到原始二进制数据。
通过 openssl 命令转换如下:
1.3.2 DER 转 PEM
- 先将 DER 二进制内容进行 Base64 编码
- 再按每行 64 个字节进行切分
- 最后在切分后的内容前后加上
----BEGIN xxx----
和----END xxx----
通过 openssl 命令转换如下:
1.3.3 实例
2.RSA
2.1 私钥部分
2.1.1 生成私钥:PKCS#1
实践发现,OpenSSL 高版本,如
3.1.3
,默认生成的是pkcs8格式的,注意区分下版本。
2.1.2 私钥:PKCS1 -> PKCS8
pem格式转der格式
2.1.3 私钥:PKCS8 -> PKCS1
2.2 公钥部分
2.2.1 导出公钥:从PKCS1私钥 导出PKCS8公钥
2.2.2 导出公钥:从PKCS8私钥 导出PKCS8公钥
2.2.3 公钥:PKCS8 -> PKCS1
2.2.4 公钥:pkcs1 -> pkcs8
2.3 扩展
2.3.1 单行私钥值format成多行
有时候配置文件里写的是单行的配置信息,想format一下,一行一行敲回车太累了。
-
解析ASN1结构,判断是PKCS8还是PKCS1
PKCS8带扩展信息,PKCS1不带。
-
根据对应的结构,添加上头尾标识字符。
比如这里添加上PKCS8的头尾信息。
3.SM2(EC)
是否支持国密,不支持的话可以参考5.1节进行安装。
3.1 私钥部分
3.1.1 生成私钥:EC格式
3.1.2 私钥:EC -> PKCS1
3.1.3 私钥:EC ->PKCS8
3.1.4 私钥:PKCS1 -> PKCS8
从EC格式转成PKCS1/PKCS8格式后,其余的命令和RSA那里就是相通的了。
3.1.5 私钥:PKCS8 -> PKCS1
注意openssl后面的形参从rsa变成了ec
3.2 公钥部分
3.2.1 导出公钥:从EC私钥 导出PKCS8公钥
3.2.2 导出公钥:从PKCS8私钥 导出PKCS8公钥
3.2.3 公钥:PKCS8
SM2公钥没有标准的PKCS#1格式
Why PEM encodings of EC public and private keys use different headers?
参考这个文章,总结下就是。
在实际使用中,并不存在 -----BEGIN EC PUBLIC KEY-----
这种格式的公钥头。
EC 公钥一般使用的是 X.509 标准的 SubjectPublicKeyInfo
结构,因此在 PEM 编码中,通常会使用 -----BEGIN PUBLIC KEY-----
头。
这是因为 EC 公钥通常存储在符合 X.509 标准的 SubjectPublicKeyInfo
结构中,而不是单独的 EC 公钥结构。
3.2.3.1 pem -> der
3.2.3.2 der -> pem
3.3 签名
3.3.1 PKCS1私钥进行签名
3.4 验签
3.4.1 PKCS1公钥验证签名
4.数字证书
4.1 查看证书序列号
4.2 获取证书中的公钥(PKCS8)
5.扩展
5.1 openssl安装
5.1.1 Linux
5.1.1.1 下载
此处以3.2.1为例
5.1.1.2 解压与安装
将安装包上传到服务器
5.1.1.3 使用
安装完成后,可以使用whereis查看位置。
5.1.2 Windows
win的话配置环境变量即可,可执行文件在bin目录下。
__EOF__

本文链接:https://www.cnblogs.com/yang37/p/16636435.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析