【密码学】SM2密钥格式的解构
本篇文章呢,依然来自于群友的一个问题,正好,我又可以来水一篇文章了,那么,我们先来看一下这个问题吧。
问题再现
❝
d71c8bff1106610ad8ed76e313561e7907cb8e1a0a191384b369d820413a8d1a
❞
这种密钥格式,如何变换为SM2的私钥格式,本文依然对原始的数据进行了处理,这个值,是我自己生成的。
前置知识
为了讲明白,这个密钥格式究竟是什么,首先,我们需要简单回顾一下SM2的相关知识,这里只是做一下简单的回顾,详细知识内容可以参考附件当中的参考资料。
SM2参数选择
p = 0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF
a = 0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC
b = 0x28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93
n = 0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123
g = (0x32c4ae2c1f1981195f9904466a39c9948fe30bbff2660be1715a4589334c74c7, 0xbc3736a2f4f6779c59bdcee36b692153d0a9877cc62a474002df32e52139f0a0)
SM2的密钥生成
尽管SM2涉及到了3个算法(签名算法、加密算法、密钥交换协议),但是他们生成密钥的方案都是统一的,因此这里不再对三个算法展开描述了,我们整体来看一下密钥生成的过程。
相比于RSA,基于椭圆曲线的密码体系,私钥的生成要简单的多,其实就是随机选择一个256位的随机数就可以了。
哎,这时候,聪明的读者可能就发现了,这上面问题再现里面的那一串Hex的字符串,不会就是一个随机的大整数吧?
没错,实际上,上面那个就是私钥,没有其他的了,那好了,本篇文章到此结束,感谢大家的观看~~
问题当然没有这么简单,既然我们聊到了SM2的密钥格式,那么不妨稍微展开聊一聊吧。
PKSC8的密钥格式
正常,我们常见的密钥格式为PKCS8的密钥格式,比如下面的样子。
通过我们之前的文章,我们知道,这个实际上是ASN.1的表示法,我们简单来看一下他的结构
openssl ec -in key.pem -text -noout
我们简单贴一个SM2的ASN.1的格式吧。
SM2PrivateKey ::= SEQUENCE {
version INTEGER, -- 私钥版本
privateKey OCTET STRING, -- 私钥
parameters [0] ECParameters OPTIONAL, -- 曲线参数
publicKey [1] BIT STRING OPTIONAL -- 公钥(可选)
}
ECParameters ::= SEQUENCE {
version INTEGER, -- 参数版本
fieldID FieldID, -- 有限域的描述
curve Curve, -- 椭圆曲线参数
base BIT STRING, -- 基点G
order INTEGER, -- 曲线的阶
cofactor INTEGER OPTIONAL -- 阶的余因子(可选)
}
FieldID ::= SEQUENCE {
fieldType OBJECT IDENTIFIER, -- 表示域类型的OID
parameters ANY DEFINED BY fieldType -- 域参数
}
Curve ::= SEQUENCE {
a OCTET STRING, -- 曲线方程的系数a
b OCTET STRING, -- 曲线方程的系数b
seed BIT STRING OPTIONAL -- 种子(用于生成曲线参数,可选)
}
SM2PublicKey ::= SEQUENCE {
algorithm AlgorithmIdentifier, -- 算法标识
publicKey BIT STRING -- 公钥(点的X和Y坐标的串联)
}
AlgorithmIdentifier ::= SEQUENCE {
algorithm OBJECT IDENTIFIER, -- 算法的OID
parameters ANY DEFINED BY algorithm OPTIONAL -- 算法参数
}
对于这个,其实也不难理解,因为,这个东西,在之前我们的文章当中,已经见到过太多次了,这里就不展开描述了。
SM2的公钥
对于上面所描述的私钥,其实非常简单,因为就是一个256位的随机数,没有太多可以聊的,我们接下来看一下公钥的样子。
从这里,可以看出,公钥其实是一个坐标,那么我们就要想办法来存一下这个的坐标了,首先,我们能想到的方式,就是直接存储,就是存两个坐标,但是呢,因为曲线是已知的,因此我们可以根据一个坐标来计算另一个,因此,我们不需要存储两个,这就有了三种存储的方式。
-
「未压缩格式」:直接存储x和y坐标,通常这会以一个04(表示未压缩)开头,后接64字节的x和y坐标值。 -
「压缩格式」:只存储x坐标和一个标志位,表示y坐标的奇偶性。 -
「混合格式」:存储x坐标、y坐标的奇偶性和完整的y坐标。
好了,其实到这里,我们如何来表示SM2的公钥也就描述完成了。
这个,依然是用ASN.1表示法来表示公钥的,这里就不过多的赘述了。
问题解决
好了,有了前面的知识,那么我们将一个随机数,变换成为pkcs#8的密钥格式就可以了,比较简单,这里就不过多赘述了。
总结
正如诗人通过笔触描绘心中的世界,密码学家也通过算法和密钥设计,构建了一个透明而安全的信息交换领域。在这个领域里,数据流如清泉般纯净,通信如诗篇般流畅。而对SM2密钥格式的深入解析,便是这场艺术创作过程中的一次精彩演绎,让我们得以窥见那些使数字通信得以安全进行的隐秘而精致的细节。好了,本篇文章,到这里就真的结束了,感谢大家的观看。
参考资料
-
GM/T0003.1—2012 SM2椭圆曲线公钥密码算法第1部分: 总则 -
GM/T0003.2—2012 SM2椭圆曲线公钥密码算法第2部分: 数字签名算法 -
https://mp.weixin.qq.com/s/qPPqxfPYnp2stMy6c4rong -
https://www.ietf.org/rfc/rfc5915.txt
原文始发于微信公众号(Coder小Q):【密码学】SM2密钥格式的解构
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论