sm2算法是国密标准的非对称算法标准。基于ecc的扩展
椭圆曲线算法
破解难度高于rsa算法。
椭圆曲线方程:y2=x3+ax+b
获取公私钥的大概步骤:
- 确认a、b,确认曲线。
- 选择一个点P为基点
- 对曲线做切线、x对称点运行。次数为 d,运算倍点为Q
- d 为私钥, Q 为公钥
密钥对的生成:
基于上面的理论,一般函数实现方式为:
- 产生随机整数 d [1,n-2]
- G为基点,计算点 P=(xP,yP)=[d]G;
- 密钥对为: (d,P) 其中,d为私钥,P为公钥
sm2签名、验签算法
签名和验签一般用在身份确认
签名
M为待签名消息,数字签名结果为(r,s) ,用户密钥对(d,P)。
实现步骤:
- e=hash(M) //获取消息散列值
- 产生随机数 k //以便即使是同一个消息,每次签名出来的结果不同。
- 使用随机数,计算椭圆曲线点(x1,y1)=[k]G
- r=(e+x1) mod n //判断:r=0 或者 r+k=n, 继续第2步。
- s= ((1+d)-1 * (k-r*d)) mod n , 若s=0,继续第2步
- r,s 为签名信息。
验签
M为明文,(r,s)为签名结果,用户公钥P
实现步骤:
- e=hash(M)
- t=(r+s) mod n
- (x,y)=[s]G + [t]P
- R=(e+x)mod n
- 计算R==?r
[s]G +[t]P的结果可以推导出等于[k]G 。有兴趣可以尝试一下。
加密
M为比特串
- 获取随机数 k
- (x1, y1) = [k]G
- S=[h]P //h为余因子
- C1=(x2,y2)= [k]P
- t=KDF(x2||y2,klen);//klen为M的长度。KDF是sm2的密钥派生函数
- c2 = M+t
- C3 = Hash(x2||M||y2)
- C = C1||C2||C3
解密
C为加密后的结果,klen为密文中C2的长度
- C1 = C里面获取 ,验证C1是否满足椭圆曲线。//C2长度确定,可以获取C1内容。
- S=[h]C1,S为无穷点,退出。
- (x2,y2)=[d]C1
- t=KDF(m2||y2,klen)
- M' = C2+t
- u=Hash(x2||M'||y2), u ?= C3
- M`为明文