4. SM2推荐曲线参数与验证
SM2 的公钥密码体制并不是“随便选一条椭圆曲线就能用”。国家标准 GB/T 32918 给出了推荐曲线,它由一组固定参数共同定义。理解这些参数的含义、掌握参数合法性检查方法、弄清点压缩与解压缩的编码规则,并警惕工程中参数注入带来的风险,是把 SM2 用对、用安全的前提。
一、推荐曲线参数的含义
SM2 推荐曲线定义在素域 Fp 上,其方程形式为 y² = x³ + ax + b。一条可用的曲线需要以下参数共同确定:
- p:有限域的素数模数,决定坐标的取值范围,所有坐标运算都在模 p 下进行。
- a、b:曲线方程系数。SM2 推荐曲线中 a = -3(即 p-3),b 为固定常数。
- n:基点 G 的阶,即满足 nG = O(无穷远点)的最小正整数,它决定私钥和标量乘法的取值范围。
- G = (xG, yG):基点,是生成公钥的固定起点,公钥 P = dG,d 为私钥。
- h:余因子,h = #E(Fp)/n,SM2 推荐曲线 h = 1,意味着曲线阶恰好等于 n,不存在小子群攻击隐患。
这些参数不是孤立的数字,而是彼此约束:p 决定域,a、b 决定曲线形状,G 必须落在曲线上,n 必须是 G 的阶,h 必须为整数。任何一项被篡改,整条曲线就可能退化,安全性随之崩塌。
二、参数合法性检查
在工程实现中,尤其是从外部导入曲线参数时,必须做合法性检查。核心检查项包括:
- p 是否为素数,且满足推荐曲线规定的位长(SM2 为 256 位)。
- 判别式非零:4a³ + 27b² ≠ 0 (mod p),否则曲线奇异,不构成椭圆曲线群。
- 基点 G 在曲线上:验证 yG² ≡ xG³ + a·xG + b (mod p)。
- n 为素数,且 nG = O,确保 G 的阶正确。
- 余因子 h = 1,或至少验证 h 与推荐值一致。
- 参数与国家标准一致:若使用推荐曲线,应逐字节比对 p、a、b、G、n,防止“看似相同实则被替换”。
三、曲线点压缩与解压缩
椭圆曲线点 (x, y) 中,y 由 x 和曲线方程确定,只差一个正负号。因此可以只传 x 加一个标志位,把点从 65 字节压缩到 33 字节,这就是点压缩。
压缩编码规则:首字节为 0x02 表示 y 为偶数,0x03 表示 y 为奇数,后接 32 字节的 x 坐标。解压缩时,先由 x 代入方程求出 y² = x³ + ax + b (mod p),再用模 p 平方根算法(如 Tonelli-Shanks)求出 y,最后根据首字节的奇偶标志选择正确的 y 值。
压缩点:02/03 || x (33 字节)
解压缩:
y2 = x^3 + a*x + b mod p
y = sqrt(y2) mod p
若 (y & 1) 与标志位不符,则 y = p - y
验证 (x, y) 在曲线上,否则拒绝
解压缩后必须重新验证点是否在曲线上,否则可能引入无效点攻击。压缩点常用于证书、密钥交换报文中节省带宽,但解压缩的每一步都要做边界与合法性判断。
四、工程中的参数注入风险
参数注入是指攻击者通过替换、篡改曲线参数,使系统在一条弱曲线或恶意曲线上运算,从而泄露私钥或伪造签名。典型场景包括:
- 曲线替换:把推荐曲线换成一条阶很小或结构已知的曲线,使离散对数易解。
- 基点替换:保持 p、a、b 不变,但把 G 换成低阶点,导致私钥落在小子群中。
- 无效点注入:在密钥交换中传入不在曲线上的点,触发异常或泄露信息。
- 参数来源不可信:从配置文件、网络或第三方库加载曲线参数,未做校验。
把上述内容串起来看:参数定义决定曲线身份,合法性检查确认曲线可用,点压缩与解压缩处理点的编码传输,参数注入防御保证运行时不偏离推荐曲线。四者环环相扣,任何一环放松,SM2 的安全性都无法保证。工程实现中,最稳妥的做法是直接使用标准常量,把校验逻辑作为导入参数的强制关卡,而不是可选项。