首页logo
  •  

jonllen

金龙,目前就职于一家软件公司,从事Java和.Net信息安全开发设计。

个人档案

jonllen
心情闪存 | 给他留言
妮称:jonllen
来自:中国. 湖南. 湘潭
简述:金龙,目前就职于一家软件公司,从事Java和.Net信息安全开发设计。
博客日历

JS版SM2国密算法的签名验证

分类:JavaScript

前段时间因工作需要,了解到在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位数字溢出后转换的值。

而C#中原来的byte[]在JavaScript里变成了Array数组,原来C#中使用的BigInteger大数计算类也原封不动移到了JavaScript中来,还有ECC曲线的Curve、ECPoint对象等等,这样只需要注册SM3、SM2算法再实现就可以了,原来C#中SM2算法就不在此叙述了。

2)SM2签名用的随机数

原来在SM2测试曲线的示例中,有人提出每次签名的结果是一样的。后面发现那里签名时用的k是固定值,所以只要签名密钥和原始数据没变,每次签名后的结果都是一样的。SM2国密标准里用的k值是随机生成的,所以SM2国密算法的签名结果每次都不一样。而SM2国密算法的加密中也生成了随机数,因此每次SM2加密结果也都不一样。

3)JS的SM2算法应用

JavaScript实现SM2国密算法的签名和验证现在应用得比较少,一般来说签名使用的私钥都封在UKey安全设备中了,为保证安全性硬件本身提供了算法接口,很少使用软算法实现。不过JavaScript作为客户端的脚本语言,可以在提交到服务器端前对数据进行加密,这个还是非常有意义的,比如可以在客户端使用公钥加密账号信息,然后在服务器端用私钥进行解密。

最后,提供一个SM2国密算法的SM2证书验签功能的Demo,完整的SM2的密钥对生成、签名、验证点这里下载。

SM2签名验证
  • (Base64)
  • (Base64)

参考资料:Github jsrsasign

标签:JavaScript
  • posted@ 2014-06-17 20:33
  • update@ 2014-06-19 09:34:16
  • 阅读(11695)
  • 评论(22)

相关文章

评论
1楼 mrfk 2014-08-07 15:12:53
朋友,你好,请教个问题,我这里写了一个java版本的SM2验签方法,自己内部是可以实现签名和验签的,但是拿底层模块加密的数据却无法验签,可能是哪些地方出问题呢
回复:你的用户id是不是都用的一样的,用公钥计算出来的Z值是一样吗?(2014-08-11 17:35:12)
2楼 mrfk 2014-08-11 17:39:39
你好,我这边已经大概查出是什么问题了,是计算z值出的问题,算法都是标准的算法,没有问题的
3楼 111 2014-10-11 09:47:04
你是大哥.牛得不行.简直膜拜得五体投地.感谢.....
4楼 111 2014-10-11 09:47:11
你是大哥.牛得不行.简直膜拜得五体投地.感谢.....
5楼 天啊 2014-10-30 16:33:22
非常感谢!
6楼 cstomcat 2015-08-11 16:28:58
您好,请问用js可以实现sm3算法吗?改造的难度大吗?
7楼 cstomcat 2015-08-11 16:29:01
您好,请问用js可以实现sm3算法吗?改造的难度大吗?
回复:可以实现的.(2015-08-16 11:31:48)
8楼 fxk 2016-03-09 14:44:14
我点击验签的时候为什么有时候会出现无效签名??
9楼 xiaofeng 2016-04-27 15:52:27
金龙,有没有研究过JS的SM4实现?
10楼 xiaofeng 2016-04-27 15:52:29
金龙,有没有研究过JS的SM4实现?
11楼 xiaofeng 2016-04-27 15:53:26
哥们。有没有研究过SM4用JS实现?
回复:没有,那个不是开放代码的软算法吗(2016-05-07 08:54:21)
12楼 aiziji911 2017-01-04 10:48:37
大神,为啥签名出来的长度不是128位呢? 按说不应该是128位吗
13楼 zxk 2017-07-24 15:03:19
你好,我想问下,js端用sm2加密,java后端解密,解密失败,不知道是不是前后端实现不一样,你那边有java实现的sm2解密么?
14楼 zxk 2017-07-24 18:45:07
你好,我现在有一个问题,我现在在前台加解密正常,在后台加解密也正常,但是前台加密后的值到后台解密不成功, 公钥和私钥用的都是一样的,js版的sm2和java版的sm2实现是不一样的吗?求教
15楼 小帅丶 2017-08-03 09:00:33
[quote]mrfk:朋友,你好,请教个问题,我这里写了一个java版本的SM2验签方法,自己内部是可以实现签名和验签的,但是拿底层模块加密的数据却无法验签,可能是哪些地方出问题呢[/quote] Java生成SM2证书有成功吗?
16楼 anjaiwook 2018-03-20 16:45:20
[quote]zxk:你好,我现在有一个问题,我现在在前台加解密正常,在后台加解密也正常,但是前台加密后的值到后台解密不成功, 公钥和私钥用的都是一样的,js版的sm2和java版的sm2实现是不一样的吗?求教[/quote]
17楼 曹帅 2018-04-10 15:08:38
我怎么没看到你的uid呢
18楼 曹帅 2018-04-10 15:08:59
我怎么没看到你的uid
19楼 haomn 2018-05-08 11:31:03
你好,我现在前台用js加密,后台用C#解密,但是解不成功。
20楼 wmy 2018-05-15 16:13:43
您好,为什么我使用您的demo验证 alert invalid?
21楼 wmy 2018-05-15 16:16:25
我错了错了,老眼昏花,又运行出来valid
22楼 349989153 2018-06-23 13:40:31
验证了一下,作者的代码是可用的,不知道有没有github地址能快速用一下。 楼上的,你们后端代码的用户ID(又叫IDa)是'1234567812345678'吗?hash算法是sm3吗?检查一下这2个应该就好了。 另外实在有不懂的地方,直接去看sm2的官方文档,写得还是挺清楚的。
23楼 JS版本的SM签名算法 2019-12-24 18:08:32
最近刚刚接触SM2算法,签名与验签过程一直很蒙,看到你的例子,想深入学习一下,可以提供一下源码么?万分感谢。289039219@qq.com
24楼 感谢大哥 2020-02-07 07:36:29
我还在纠结 微信小程序的那个版本,没想到你早都有了
回复:-_-)))(2020-07-14 20:47:36)
25楼 私钥计算公钥 2020-02-07 07:39:55
如果有个私钥计算公钥,那就完美了,就前端完整的走通了,客户本地存个私钥即可
发表评论
*必填
回复通知我
*必填