1. SM2 算法概述
1.1 椭圆曲线密码学基础
椭圆曲线密码学,说白了就是利用椭圆曲线上的点构成一个群,然后在这个群里做公钥密码。你想想看,一个曲线方程 y² = x³ + ax + b,加上一个无穷远点,就能定义加法运算——点与点相加,得到另一个点。这跟初中学的加法不是一回事,但形式很像。
我最早接触 ECC 是在做物联网安全模块的时候。当时负责人说“用 ECC 密钥比 RSA 小得多,但安全强度差不多”。我当时半信半疑,后来一算才知道:256 位的 ECC 密钥,等效于 3072 位的 RSA 密钥。嗯,省带宽省存储,确实香。
SM2 使用的椭圆曲线由国密标准 GM/T 0003 规定,曲线参数完全公开。主要参数包括:
- p:素数,定义有限域 Fp 的大小
- a, b:曲线方程系数
- G:基点,生成子群的公开点
- n:基点 G 的阶,素数
- h:余因子,通常为 1
为什么不直接用国际标准曲线?SM2 的曲线参数是国内自主设计的,没有后门嫌疑。我在项目中验收时,客户就明确要求使用国密曲线,说“用国际标准万一哪天被断供了呢”。这话糙理不糙。
小提示:椭圆曲线上的“加法”不是画图上的几何加法。实际实现用射影坐标加速,别手写仿射坐标的求逆运算,慢得离谱。
1.2 SM2 国家标准(GM/T 0003)
GM/T 0003 全称《SM2 椭圆曲线公钥密码算法》,包含三个子算法:
| 子算法 | 功能 | 标准编号 |
|---|---|---|
| 数字签名算法 | 签名与验签 | GM/T 0003.2 |
| 密钥交换协议 | 双方协商会话密钥 | GM/T 0003.3 |
| 公钥加密算法 | 加密与解密 | GM/T 0003.4 |
我记得第一次看标准文档时,签名算法里有个 r = (e + x₁) mod n 的公式,和 ECDSA 的 r = x₁ mod n 不一样。当时调了一整天才发现,SM2 的签名结构中把消息摘要 e 也混进去了。这设计其实是为了防止某种攻击,具体可以查标准附录。
SM2 签名流程简记:
- 计算消息摘要
e = H(ZA || M),其中 ZA 是用户标识、曲线参数、公钥的哈希。 - 生成随机数
k,计算椭圆曲线点(x₁, y₁) = kG。 r = (e + x₁) mod n,若r = 0或r + k = n则重试。s = ((1 + dA)⁻¹ · (k − r · dA)) mod n,若s = 0则重试。- 输出签名
(r, s)。
避坑:签名中的 k 必须真随机,不能固定,也不能泄露。我曾经在某个项目中见过测试代码里用固定 k = 1,结果签名直接暴露了私钥。嗯,那哥们后来被拉去写文档了。
1.3 应用场景与安全强度
SM2 在国内就是个“万金油”密码算法。电子政务、金融 IC 卡、移动支付、车联网……只要涉及国产化,基本都绕不开它。我参与过一个省级电子证照平台,所有签名验签全部用 SM2,原因是政策要求“核心密码必须自主可控”。
常见应用场景:
- 数字签名:电子合同、订单防篡改、软件固件签名
- 密钥交换:TLS 国密套件(SM2 + SM3 + SM4)、VPN 密钥协商
- 公钥加密:加密传输对称密钥、数字信封
- 身份认证:挑战-响应协议、登录令牌
安全强度方面,SM2 使用 256 位素域曲线,密钥长度 256 位。目前已知最佳攻击(Pollard's Rho)的计算复杂度约为 2¹²⁸,相当于 128 位对称安全强度。对标一下:
| 算法 | 密钥长度(位) | 等效对称强度(位) |
|---|---|---|
| SM2 | 256 | 128 |
| RSA | 3072 | 128 |
| ECDSA (P-256) | 256 | 128 |
说白了,SM2 256 位的安全级别和 RSA 3072 位持平,但性能好得多。我在嵌入式 ARM Cortex-M4 上测过,SM2 签名大约 15ms,验签 25ms,而同样强度的 RSA 签名要 200ms+。差距非常明显。
核心结论:SM2 在 128 位安全等级下,是目前公钥密码体系里性能与安全性平衡最好的选择之一,特别适合资源受限的 IoT 设备。