如果觉得写得不错,烦请微信搜索公众号 "郑州行疆户外" 了解程序员的户外业余喜好。
转载:https://www.xuebuyuan.com/1473900.html
一般情况下,计算数字签名时应执行以下操作:
1. 计算原始数据的 Hash 值;
2. 将 Hash 值作为输入,计算签名函数的输出。并不是对原始数据直接签名,而是对 Hash 值签名。
验证签名时应执行以下操作:
1. 计算原始数据的 Hash 值;
2. 将 Hash 值和签名值作为输入,计算验签函数的输出,根据输出判断签名为“有效”或“无效”。
这只是一个简单描述,实际上 PKCS#1 中规定的签名和验签过程要复杂得多。
计算 SM2 签名和验签的过程有点特殊,因为根据国内的行业标准,SM2 签名算法要和 SM3 Hash 算法搭配使用,并且计算 SM2 签名的输入并不是待签名数据的 SM3 杂凑值,而是一个预处理阶段的输出。
预处理分为两步:
1. 定义一个级联生成的字节流 T1 = ENTL || ID || a || b || x_G || y_G || x_A || y_A,
其中 || 表示字节流的拼接,
ENTL 是用两个字节表示的签名者 ID 的比特长度(注意不是字节长度),
ID 为签名者的标识,
a, b, x_G, y_G 都是标准中给定的值, x_A 和 y_A 是签名者的公钥,
对字节流 T1 计算 SM3 杂凑值,得到的输出为 Z = SM3(T1)。
这一步并没有用到待签名数据。
2. 将待签名数据用 M 表示,将 Z 与待签名数据级联,得到 T2 = Z || M,计算 T2 的杂凑值,即 SM3(T2),SM3(T2)才是 SM2 签名函数的真正输入。
注意预处理中用到的数都采用 big-endian 表示法!
从上面的预处理过程可以看出,当验证签名时,也要经过同样的预处理过程,将预处理阶段的输出、签名值作为验签函数的输入。
网上有很多 SM3 杂凑算法的开源实现,比如这个网址上提供的:https://github.com/siddontang/pygmcrypto/tree/master/src 。但是一般能找到的 SM3 实现都没有提供预处理功能,所以是不能直接用作计算 SM2 签名和验签的输入。在上面网址提供的
SM3 实现基础上,本文将给