前段时间因工作需要,了解到在Github上已经有人实现了用JavaScript来写签名和验签,支持RSA、ECC、DSA等算法,还能解析X.509证书,一时觉得JavaScript是无比强大。后面就研究了下JavaScript版的ECC算法签名验证,自己再扩展实现了SM2国密算法的签名验证。
基于现有已实现的C#版SM2国密算法的签名验证,再结合原来JavaScript的ECC算法,使用JavaScript实现SM2国密算法的签名验证相对简单,只需要将C#语言翻译成JavaScript语言实现。不过中间还是遇到了些问题,主要是在JavaScript计算SM3摘要值大数的运算上还是有些不同。
1)JS计算SM3摘要
在做SM2签名之前,需要先计算出原始数据的SM3摘要值,需要计算出z值,这其中就用到了大量的移位运算。JavaScript本身支持移位异或运算,但在C#中数字有int、long等多种类型,而在JavaScript中都用Number类型,这些不同类型运算要分别处理。C#的long类型表示64位有符号的整数,为区分32位整数在值后面加L显示定义。而在JavaScript就要把整数转成64位长度来计算。
C#中默认不检查运算上溢\下溢,除开使用常量编译器会提示,或显示使用了checked关键字检查溢出。原来在C#中使用int类型运算的,并在计算后可能会超出Int32.MinValue~Int32.MaxValue范围的,在JavaScript中就需要截取超出32位长度的高位。并且要按优先顺序计算,即a+b+c必须先计算出(a+b)结果是否溢出再加c,不能直接先计算(a+b+c)总结果再计算溢出后32位的值。因此我用JavaScript写了个C#中的unchecked情况下Int32