在前段时间,已用JavaScript实现SM2算法的签名验证,下面来讲下JS的SM2算法的非对称加解密。这个在客户端加密的应用场景可能会更多些,比如我们平时登录的网站的密码,如果没有使用SSL证书加密一般会是明文传输这样会很不安全,这时可以考虑结合使用非对称算法加密,将服务器端的公钥输出在客户端,客户端使用公钥加密,登录时密码以密文方式传给服务器端再由相应私钥解密得到明文数据。
SM2加密
SM2非对称加密的结果由C1,C2,C3三部分组成。其中C1是生成随机数的计算出的椭圆曲线点,C2是密文数据,C3是SM3的摘要值。最开始的国密标准的结果是按C1C2C3顺序的,新标准的是按C1C3C2顺序存放的,因此我这边在做SM2加密时新增加了加密结果的顺序参数,以配置兼容之前的SM2算法加密。
SM3算法
SM2国密算法有点不一样的是,同时使用了SM3摘要算法验证,即SM2加密结果中的C3为SM3摘要。这次也使用上次JS签名进行SM3摘要计算方法,修正了JS移位运算转换为Byte字节问题,对于溢出部分截取后8位处理。
BigInteger大数运算
用JS来写算法毕竟对客户端浏览器的脚本执行效率还是有很大考验的。SM2算法中进行大量的移位和异或计算,对数值的运算很多。目前JS中的大数BigInteger类处理,IE浏览器中会“友情提示”:停止运行此脚本吗?此页面上的脚本造成Web浏览器运行速度减慢。如果继续运行,您的计算机将可能停止响应。可想而知在IE里面用JS跑SM2算法,在运算时开销很大好像遇到“死循环”了,而在用Firefox浏览器测试用JS做SM2算法,虽然没有直接提示脚本正忙,但仍然反映速度不乐观。因此在JavaScript处理大数的运算这块还有很多需要优化的。
最后,提供本次JS实现SM2算法加解密的示例页面,首先可以先生成SM2密钥对,然后再做SM2加密和解密,最下面还提供了使用SM2证书做非对称加密的示例,密文的格式默认是按C1C3C2顺序以Base64编码的,应该可以和密码机或UKey做解密互通的。SM2算法加解密地址为:http://www.jonllen.com/upload/jonllen/case/jsrsasign-master/sample-sm2_crypt.html。