SM2算法是中国国家密码局推出的国产化算法,是基于椭圆曲线的非对称算法,相对于RSA算法,SM2具有密钥更小,运算速度更快,相同密钥长度下具有更高安全性等优势。
SM2算法定义了两条椭圆曲线,一条基于F§上的素域曲线,一条基于F(2^m)上的拓域曲线,目前使用最多的曲线为素域曲线,本文介绍的算法基于素域曲线上的运算,素域曲线方程定义如下:
y 2 − x 3 + a x + b y^2-x^3+ax+b y2−x3+ax+b
###1.2 SM2 曲线参数定义
SM2算法定义了5个默认参数,即有限域F§的规模p,椭圆曲线参数a,b,椭圆曲线的基点G(x,y),与G的阶n。
国密算法标准中给出了对应的默认值,默认值如下:
p:FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF
n:FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123
a:FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC
b:28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93
Gx:32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7
Gy:BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0
牢记上面四个默认参数与一个基础点,在后面运算过程中会用到上面的所有参数。
SM2作为非对称算法拥有公钥与私钥,对于SM2中公私钥的结构如下:
私钥:d
符合要求的32byte(256bit)随机数
公钥:(x,y)
,实际一个坐标点,依据私钥d
计算所得
依据私钥计算公钥的逻辑不在本文介绍范围。
SM2加密数据使用公钥(x,y)
进行加密,加密结果为c1c3c2
部分算法中定义为c1c2c3
,下面介绍密文中各个结构实际含义:
c1: 随机数K与G(x,y)的多倍点运算结果,结果也是一个点,记录为(kx,ky)
c2: 实际密文值
c3:使用SM3对于 kx||data||ky的hash值,在解密时校验解密结果是否正确
在实际算法实现中,c1的运算逻辑如下:
c1 = k·G(x,y)
k
是一个随机数,随机数的生成逻辑如下:
选取一个随机数k,使得随机的k的取值范围为[1,n-1],这块的n是1.2章节中提到的默认值
c2是真正的数据密文,计算逻辑如下:
c2 = 密钥流 (异或)data
密钥流的计算逻辑如下:
1. 复用计算c1时产生的随机数k
2. 计算 kpk(x,y),得到kpx,kpy
3. 根据data的长度与kpx,kpy生成与data等长的密钥流,用于c2的最终计算
整体密钥流计算采用KDF方法计算,KDF可以理解成根据输入的因子,产生期望长度的数据流,目前直流的KDF计算采用HASH方法。SM2中的KDF使用的是SM3摘要。
c3
是一个SM3的摘要值,作用是用于解密时校验解密出的原文数据的正确性,c3
的计算逻辑如下:
c3 = HASH(kpx,data,kpy)
在解密时需要在解密出原文后计算HASH值做最后确认,确认一致后认定解密成功,不一致则解密失败。
SM2的解密流程实际是根据c1计算出加密时使用的密钥流,使用密文数据与密钥流进行异或得到数据明文,后续在确认计算出的摘要值与密文中c3是否一致。
1. 从密文中分离出 c1(x,y)
2. 使用私钥d与c1进行多倍点运算,得到计算结果 (cx,cy),d·c1(cx,cy)
3. 根据c2长度计算密钥流,KDF(cipherlen,cx,cy)
这里为什么私钥d与c1的运算结果等于k与G(x,y)运算结果,请参网上的其他帖子或数学证明过程,不在本文的讨论范围。
上面我们得到了密钥流的中间结果,我们根据密钥流来计算明文:
原文 = 密钥流 (异或) 密文
接下来我们计算解密后的摘要值与c3是否相等,计算流程如下:
1. 基于以上的运算结果的cx,cy与得到的原文
2. SM3(cx,计算得到的明文,cy)
3. 对比计算结果与c1,一致解密成功,不一致则解密失败