证书-双证书请求文件
1.背景
关于数字证书、数字信封、OID等基本知识,此文不做赘述。
在传统的数字信封体系中,我们的流程大概这样的。
这里有个值得注意的点是:
节点1用于加密对称密钥的公钥和节点3用于签名的私钥,它们是否可以是同一对。
基于这个思想,我们有了单证书体系和双证书体系。
其原因之一就是,从功能角度隔离开我们的加密秘钥对和签名密钥对。
根据“中国金融认证中心标准-SM2 双证书申请及下载规范”,我们可以看到一个双证书的基本流程。
-
产生签名密钥对和交互密钥对。
-
生成 Base64 编码的 SM2 双证书请求。
-
向服务器端提交 SM2 双证书请求。
-
解析服务器端返回的报文数据,并解密加密证书私钥。
-
导入签名公钥证书、加密公钥证书、加密证书私钥。
2.双证书
以国密SM2为例
上面我们知道,所谓的双证书,即。
- 专门用于签名验签
- 专门用于加密解密
注意,在中国金融认证中心标准-SM2 双证书申请及下载规范中,此处的加密秘钥不是由我们的本地生成的,而是由CA生成。
整个逻辑大致交互逻辑如下:
- 本地生成签名公私钥对
- 本地生成临时公私钥对(注意,非加密秘钥对,仅仅在生成请求证书阶段使用)
- 结合签名公钥、临时公钥,生成双证书请求文件。
- CA签发签名证书
- CA生成加密公私钥对(并使用刚才我们的临时公钥加密加密秘钥对中的私钥)
- 下载CA签发的签名证书、加密证书、加密私钥
- 使用临时私钥解密加密过的私钥,得到最终的加密私钥。
3.双证请求文件
请求文件、CSR、P10,不严格的场景下,你可以当做是同一个东西。
3.1 格式描述
3.1.1 整体格式
SM2 双证书请求的 ASN.1 数据格式。
- ccertificationRequestInfo: SM2 双证书请求信息。
- signatureAlgorithm:签名算法 ID,文档中OID取值为:1.2.156.10197.1.501。
- signature:使用签名私钥,对 certificationRequestInfo 节点的签名结果。
这里提到了oid,可以在这里查询。
然后,这里的{{ SignatureAlgorithms }}
是什么意思呢?
-
AlgorithmIdentifier:这是一个ASN.1的标准类型,用于标识算法。它通常包含两个字段:算法OID(对象标识符)和可选的参数。
-
{{ SignatureAlgorithms }}:表示
AlgorithmIdentifier
的值必须来自SignatureAlgorithms
的集合。
嗯,就是下面这个。
3.1.2 CertificationRequestInfo
-
version:版本号,本文档中取值为 0x00。
-
subject:公钥证书 DN。详细介绍,请参考 PKCS#10。
-
subjectPKInfo:签名公钥信息。
-
attributes:属性信息。
3.1.3 SubjectPublicKeyInfo
-
algorithm:ECC 公钥算法 OID,在本文档中,取值为:1.2.840.10045.2.1。
-
parameters:SM2 公钥算法 OID,在本文档中,取值为:1.2.156.10197.1.301。
-
subjectPublicKey:SM2 公钥数据,结构如下。
3.1.4 attributes
- password:默认取值:111111。
- tempPublicKeyOID:交互公钥标识 OID,本文档中取值为:1.2.840.113549.1.9.63。
- tempPublicKey:交互公钥 TempPulicKey 的 OCTECT STRING 编码。
3.1.5 交互公钥
-
version:版本号,本文档中取值为:0x01。
-
tempPublicKeyData:交互公钥数据,结构如下。
3.2 示例文件
首先,给出文档中的demo双证请求文件。
我们使用ASN.1在线解析工具,可以看到大体结构,上文中对细节处已经做了框选,此处不赘述。
看起来复杂,实际也很复杂,哈哈。
但是别慌,跟咱们前面的格式描述那里对应上就好了。
就像咱们Java的实体类一样,没啥特别的,只不过走了ASN1编码而已。
3.3 代码
本文基于Java构建
4.结果文件解析
4.1 分析
根据规范,将会收到3个结果文件。
- SignCert.cer:签名对应的公钥证书
- EncCert.cer:加密对应的公钥证书
- PrivateKey.key:加密过的公私钥文件(使用我们的临时公钥加密)
由规范指引,我们可以得到解密的具体逻辑。
- 根据
,
分隔,提取密文数据。 - 解析密文数据,得到实际密文。
- 使用临时公钥解密密文,得到秘钥值。
注意,直接移除,
后得到的数据并不是直接的SM2解密源文,它是具有如下结构的(回顾3.1.5节)。
4.2 代码
注意点如下:
- 返回的数据里面会解析出version和encryptedKeyData两个部分的数据,encryptedKeyData才是我们实际解密的源数据。
- 使用BC库解密的时候,私钥前加00/密文前加04/公钥前加04。
- 经过验证,模式使用C1C3C2。
关于为啥咱们BC库里密文前要加04,你可以参考这个issue:hutool-SM2私钥解密文件报错Invalid point encoding 0x30
当然,咱们此处没有用hutool,不过原因你可以研究下。
具体代码参考:easy-cryptography
__EOF__

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