SM2算法原理:椭圆曲线密码体制、密钥生成、签名与验签、加密与解密
聊到国密改造,绕不开的核心就是SM2算法。我个人觉得,理解SM2不能光看数学公式,得把它当成一套“如何在金融交易中安全发消息”的完整方案来看。
SM2基于椭圆曲线密码体制,也就是ECC。你想想看,传统的RSA靠大整数分解,密钥越长越安全。而椭圆曲线靠的是“椭圆曲线上的离散对数问题”,在同样的安全强度下,密钥可以短很多。说白了,就是更省资源、更快。
椭圆曲线密码体制:从数学到工程
数学上,SM2定义在素域Fp上。公式是 y² = x³ + ax + b。嗯,这里要注意,国家规定了具体的参数a、b、p。这些参数是固定的,我们在SDK里不用自己算,直接用就行。
说白了,椭圆曲线就是一个点集合。你在曲线上取一个基点G,私钥是一个大整数d,公钥就是d*G。这就好比你在操场上从起点走d步,你到了终点,别人看到终点却很难反推出你走了多少步。
我在项目中遇到过一个问题:有人尝试自己实现参数验证,结果p参数长度少了一个字节,导致整条曲线都不合法。搞得我排查了半天,最后还是用标准库重新初始化才搞定。个人习惯,直接用SM2的标准曲线参数,不要自己手写。
| 参数 | 说明 | 典型值(SM2标准) |
|---|---|---|
| p | 素域模数 | FFFFFFFE FFFFFFFF ... |
| a | 椭圆曲线参数 | FFFFFFFE FFFFFFFF ... |
| b | 椭圆曲线参数 | 28E9FA9E 9D9F5E34 ... |
| G | 基点坐标(x,y) | 固定值 |
| n | 基点G的阶 | FFFFFFFF ... |
SM2密钥生成:安全的起始点
密钥生成的流程不复杂,但这里的“随机数”是命门。
- 生成随机数d:系统生成一个1到n-1之间的随机整数。这就是私钥。
- 计算公钥P:P = d * G,也就是私钥乘以基点,得到另一个椭圆曲线上的点。
- 输出:私钥d(必须保密),公钥P(公开分发)。
SM2的公钥有两种格式:压缩格式和非压缩格式。压缩格式只存储点的x坐标,再加上一个奇偶标识。非压缩格式完整保存x和y坐标。我个人在实际对接中,绝大多数情况下用非压缩格式,兼容性最好。
SM2签名与验签:不可否认性的核心
签名是什么?就是证明这消息是我发的,而且事后不能抵赖。在金融行业,比如一笔转账指令,一定要用SM2签名,才能保证交易的有效性。
SM2签名算法基于椭圆曲线,签名结果由两个大整数(r, s)组成。验签时,对方用公钥和原始消息,验证这个(r, s)是否有效。
你想想看,为什么SM2的签名比其他方案更优?因为它结合了椭圆曲线的高安全性和认证算法的高效率。它每一步都是国密标准严格定义的,不存在什么“可选的步骤”。
// SM2签名流程伪代码(简化)
// 输入:私钥d,消息M
// 输出:签名值(r, s)
1. 计算摘要 e = SM3(M) // SM3哈希
2. 生成随机数 k
3. 计算点 (x1, y1) = k * G
4. 计算 r = (e + x1) mod n
5. 计算 s = ((1 + d)^(-1) * (k - r * d)) mod n
6. 输出 (r, s)
SM2加密与解密流程:端到端的数据保护
加密和解密与签名验签是两套不同的流程。加密时用接收方的公钥,解密时用接收方的私钥。说白了,只有持有私钥的人才能解开。
SM2的加密流程是混合加密:先用SM2算法协商出一个共享密钥,然后用对称加密算法(通常是SM4)来加密实际数据。这样既发挥了非对称密钥管理方便的优势,又利用对称加密的高效率。
加密流程:
- 接收方公钥P_B:用公钥加密数据。
- 生成临时密钥对 (k, C1):C1 = k * G。
- 计算共享点 S = k * P_B。
- 使用KDF(密钥派生函数)从S中导出对称密钥t。
- 用t加密明文,得到密文C2。
- 计算MAC消息认证码C3,保证完整性。
- 输出:C = C1 || C2 || C3。
解密流程:
- 接收方私钥d_B:用私钥解密。
- 从C中提取C1、C2、C3。
- 计算共享点 S = d_B * C1。
- 用同样的KDF派生对称密钥t。
- 用C3验证C2的完整性。
- 用t解密密文C2,得到明文。
实际对接中的常见问题
我和多家银行合作过,发现SM2接入改造做得好的和做得烂的,差距就在细节上。下面几个点,是我个人认为最容易踩坑的地方:
| 问题点 | 现象 | 解决方案 |
|---|---|---|
| 密钥格式不统一 | 一方用PEM,一方用DER,解析失败 | 统一使用DER编码或X.509证书标准 |
| 签名数据编码问题 | 签名值r/s长度不定,导致验签失败 | 严格执行固定长度输出,补齐前导零 |
| 加密密文拼接顺序 | C1 || C2 || C3 顺序搞错 | 严格按照国密标准顺序 |
| 随机数重用 | 两次签名用的随机数一样 | 每次签名必须重新生成真随机数 |
好了,以上就是SM2算法的核心原理。从椭圆曲线基础,到密钥生成、签名验签、加解密流程,每个环节都和你系统的最终安全性挂钩。理解了这些,后面我们正式进入SDK接入改造时,你就会清楚每一步要做什么了。