sm2
约 2008 字大约 7 分钟
2025-07-17
1. SM2标准操作
SM2算法是中国商用密码标准之一,它基于椭圆曲线密码学(ECC),提供了数字签名、密钥交换和公钥加密等核心功能。SM2的设计考虑了国家安全需求,旨在提供高强度的数据保护和身份认证。本节将深入探讨SM2的各项标准操作。
1.1 密钥生成
SM2的密钥生成过程是所有密码操作的基础。它涉及以下步骤:
- 选择椭圆曲线参数:SM2标准定义了一组特定的椭圆曲线参数,包括曲线方程、基点 G、阶 n 和辅助参数。这些参数是公开且固定的,确保了算法的互操作性和安全性。
- 生成私钥 dA:私钥 dA 是一个随机生成的大整数,其范围在 [1,n−1] 之间。这个私钥必须严格保密,是用户身份的唯一凭证。
- 计算公钥 PA:公钥 PA 是通过将私钥 dA 与椭圆曲线的基点 G 进行标量乘法运算得到的,即 PA=dA⋅G。公钥是公开的,可以安全地分发给任何人。
1.2 加密
SM2加密是一种非对称加密方案,它允许使用接收者的公钥对数据进行加密,而只有持有相应私钥的接收者才能解密。SM2加密过程通常遵循以下步骤:
- 随机数生成:选择一个随机数 k∈[1,n−1]。
- 计算椭圆曲线点:计算 C1=k⋅G。
- 计算共享秘密:计算 S=h⋅k⋅PB,其中 PB 是接收者的公钥,h 是一个余因子(通常为1)。如果 S 是无穷远点,则重新选择 k。
- 密钥派生:从 S 的坐标中派生出对称加密密钥 t。
- 异或操作:将明文 M 与 t 进行异或操作得到 C2,即 C2=M⊕t。
- 哈希计算:计算明文的哈希值 C3=Hash(x2∣∣M∣∣y2),其中 (x2,y2) 是 S 的坐标。
- 形成密文:最终的密文由三部分组成:(C1,C2,C3)。
1.3 解密
SM2解密是加密的逆过程,只有拥有相应私钥 dB 的接收者才能执行。解密过程如下:
- 计算共享秘密:使用私钥 dB 和密文中的 C1 计算 S′=h⋅dB⋅C1。如果 S′ 是无穷远点,则解密失败。
- 密钥派生:从 S′ 的坐标中派生出对称加密密钥 t′。
- 异或操作:使用 t′ 对密文 C2 进行异或操作得到明文 M′=C2⊕t′。
- 验证哈希:计算解密得到的明文 M′ 的哈希值 Hash(x2′∣∣M′∣∣y2′),并与密文中的 C3 进行比较。如果两者不相等,则解密失败,表明密文被篡改或私钥不匹配。
- 输出明文:如果验证通过,则 M′ 就是原始明文。
1.4 签名
SM2数字签名提供消息的完整性和发送者的不可否认性。签名过程涉及以下步骤:
- 预处理:对签名消息 M 进行预处理,包括将用户的身份信息 IDA 和公钥 PA 组合,计算一个 ZA=Hash(ENTLA∣∣IDA∣∣a∣∣b∣∣xG∣∣yG∣∣xA∣∣yA),其中 ENTLA 是 IDA 的比特长度,a,b,xG,yG 是椭圆曲线参数,xA,yA 是公钥 PA 的坐标。
- 计算哈希值:计算待签名消息的哈希值 e=Hash(ZA∣∣M)。
- 随机数生成:选择一个随机数 k∈[1,n−1]。
- 计算椭圆曲线点:计算点 (x1,y1)=k⋅G。
- 计算 r:计算 r=(e+x1)(modn)。如果 r=0 或 r+k=n,则重新选择 k。
- 计算 s:计算 s=(dA⋅(e+x1)−k)⋅(1+dA)−1(modn)。如果 s=0,则重新选择 k。
- 形成签名:数字签名由一对整数 (r,s) 组成。
1.5 验签
验签是验证SM2数字签名有效性的过程,确保消息的完整性和签名者的身份。验证过程如下:
- 预处理:与签名过程类似,计算 ZA=Hash(ENTLA∣∣IDA∣∣a∣∣b∣∣xG∣∣yG∣∣xA∣∣yA)。
- 计算哈希值:计算待验证消息的哈希值 e=Hash(ZA∣∣M)。
- 验证 r,s 范围:检查签名中的 r,s 是否在 [1,n−1] 范围内。
- 计算 t:计算 t=(r+s)(modn)。如果 t=0,则验证失败。
- 计算椭圆曲线点:计算点 (x1′,y1′)=s⋅G+t⋅PA。
- 计算 R:计算 R=(e+x1′)(modn)。
- 比较:如果 R=r,则签名验证成功;否则,验证失败。
2. SM2 拆分应用
“SM2拆分”通常指的是将SM2算法的某些核心功能或密钥管理环节进行分布式或多方协同处理,以提高系统的安全性、容错性或实现更复杂的信任模型。这种拆分是基于密码学中的多方计算(MPC)和门限密码学概念。
2.1 拆分密钥
第一通信方:
- 生成私钥: D1 是一个随机生成的大整数,其范围在 [1,n−1] 之间。
- 生成公钥: 计算在 Fq 上的逆元 D1−1,并计算点 P1=D1−1∗G, 将 P1 发送给第二通信方。
第二通信方:
- 生成私钥: D2 是一个随机生成的大整数,其范围在 [1,n−1] 之间。
- 生成公钥: 计算在 Fq 上的逆元 D2−1,并计算最终的公钥 P2=D2−1∗P1−G,将 P2 公钥作为公钥。
2.2 拆分加密
加密则与 SM2 加密方式相同,可以参考 SM2 加密
2.3 拆分解密
第一通信方:
- 子私钥生成:第一通信方生成自身的子私钥 D1,第二通信方生成自身的子私钥 D2。
- 第一部分解密:第一通信方从密文 C 中提取出比特串 C1,并验证 C1 是否为椭圆曲线 E 上的非无穷远点。若验证通过,计算 T1=D1−1∗C1,并将 T1 发送给第二通信方。
- 第二部分解密:第二通信方接收 T1 后,计算 T2=D2−1∗T1,并将 T2 发送给第一通信方。
- 完整解密:第一通信方接收
T2后,计算(x2, y2) = T2 - C1[cite: 1][cite_start]。然后通过预定的密钥派生函数KDF(x2 || y2, klen)得到对称解密密钥t[cite: 1][cite_start]。接着,从密文C中提取出比特串C2[cite: 1][cite_start],计算M'' = C2 ⊕ t得到部分明文 [cite: 1][cite_start]。最后,第一通信方计算Hash(x2 || M'' || y2)得到u[cite: 1][cite_start],并与密文中的C3进行比较 [cite: 1][cite_start]。如果u等于C3,则将M''作为完整的明文输出 [cite: 1]。
2.3 拆分签名
- 子私钥生成:第一通信方生成自身的子私钥 D1,第二通信方生成自身的子私钥 D2。
- 第一方操作:第一通信方生成待签名消息 M 的消息摘要 e (通过 Hash(Z∣∣M′),其中 Z 是共同身份标识) 和第一部分签名 Q1=k1∗G ( k1 为随机数) 。随后将 e 和 Q1 发送给第二通信方。
- 第二方操作:第二通信方收到 e 和 Q1 后,生成随机数 k2 和 k3。计算 Q2=k2∗G。然后计算 (x1,y1)=k3∗Q1+Q2,并计算 r=(x1+e)modn。如果 r 不为 0,则计算 s2=(D2∗k3)modn 和 s3=(D2∗(r+k2))modn。最后,第二通信方将 r, s2, s3 发送给第一通信方。
- 完整签名生成:第一通信方接收 r, s2, s3 后,根据自身的子私钥 D1 和随机数 k1,计算 s=((D1∗k1)∗s2+D1∗s3−r)modn。如果 s 不为0且不等于 n−r,则将 (r,s) 作为完整签名输出。
