VUE使用 sm-crypto 加解密以及签名验签遇到的坑 (后端java)
1.首先 一步一步来 安装国密npminstall--savesm-crypto2.具体方法都有NPM 上都有国密即国家密码局认定的国产密码算法。主要有SM1,SM2,SM3,SM4。密钥长度和分组长度均为128位。1:SM1 为对称加密。其加密强度与AES相当。该算法不公开,调用该算法时,需要通过加密芯片的接口进行调用。2:SM2为非对称加密,基于ECC。该算法已公开。由于该算法基于ECC,故其
1.首先 一步一步来 安装 国密
npm install --save sm-crypto
2.具体方法都有NPM 上都有
国密即国家密码局认定的国产密码算法。主要有SM1,SM2,SM3,SM4。密钥长度和分组长度均为128位。
1:SM1 为对称加密。其加密强度与AES相当。该算法不公开,调用该算法时,需要通过加密芯片的接口进行调用。
2:SM2为非对称加密,基于ECC。该算法已公开。由于该算法基于ECC,故其签名速度与秘钥生成速度都快于RSA。ECC 256位(SM2采用的就是ECC 256位的一种)安全强度比RSA 2048位高,但运算速度快于RSA。
3:SM3 消息摘要。可以用MD5作为对比理解。该算法已公开。校验结果为256位。
4:SM4 无线局域网标准的分组数据算法。对称加密,密钥长度和分组长度均为128位。以上阐述借鉴的他人的描述
一共有两对密钥:一对儿服务端的;一对儿前端的
//服务端-gm公钥-用于加密和验签[服务端公钥前端拿]
var publicKeyServer = 'xxxxx';
///服务端-gm私钥-用于解密和生成签名[服务端私钥自己拿]
var privateKeyServer= 'xxxxx';
//前端-gm公钥-用于加密和验签[前端公钥后端拿]
var publicKeyWeb = 'xxxxxxx';
//前端-gm私钥-用于解密和生成签名[前端私钥自己拿]
var privateKeyWeb = 'xxxxxxx';
所以 就是前端拿服务端的公钥publicKeyServer 进行加密跟验证签名 ;留自己的私钥 privateKeyWeb 进行解密跟生成签名;同理服务也是如此拿前端公钥及留下自己的私钥
我要说的是 我在加解密的时候 const cipherMode = 1 // 1 - C1C3C2,0 - C1C2C3,默认为1 这个东西啊 你一定得配合后端来 ,因为你不确定后端是用的什么加密方式,还存在一个补位的问题
什么意思呢?就是 在加密的串前加上04,后端才能解密成功,同样后端加密后也会返回带04的加密串给前端(因为后端也是直接用别人的工具类),前端加密遇到04 的加密串且cipherMode 为1的话必须去掉04 才能解密成功
const sm2 = require('sm-crypto').sm2;
const cipherMode = 1 // 1 - C1C3C2,0 - C1C2C3,默认为1
var publicKeyServer = 'xxxxxxxxxxx';
var privateKeyWeb = 'xxxxxxxx';
//此处若把加密串a给服务端则加上 04+a
var a=sm2.doEncrypt('SM2加解密注意事项', publicKeyServer, 1)
console.log("SM2加密内容:"+a);
//如果自己前端解密后端返回的带有04开头的字符串则去掉04后解密
var b=sm2.doDecrypt(a,privateKeyWeb,1) // 解密结果
console.log("sm2解密内容:"+b);
3.签名验证问题
如果是正常安装npm install --save sm-crypto 的话你会发现 这里面有很多种签名的方式 如果你联调都通了 那就不用看下面得了
这个库的签名有很多种方式:但都不适用我目前遇到的问题 就是无法验证签名 后端是java 用的依赖如下:
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.65</version>
</dependency>
我们遇到的问题 就是这个所有的签名方式都过了 但后端都无法验证签名 所以就又找呗~找到这个https://github.com/JuneAndGreen/sm-crypto/issues/20库的GitHub上 issues 上 有人问出"SM2自己签名验签应该没啥问题,但是和别的语言是不通的"
其中有个人提出 在他自己的GitHub上有个测试例子和java+js 的例子
他的项目中有提到签名的问题 然后按照他的方式解决了签名验签的问题
不用 sm-crypto 里的所有签名方式 什么der,hash,userid,都无可奈何
就用 https://github.com/lpilp/forhuahua 他的项目中有提到签名的问题 然后按照他的方式解决了签名验签的问题
目前的java的版本基本基于BC库的,新版的1.66BC库已经可以和其他语言互通了,它默认的返回是 {der: true, hash: true} 这种的,验的时候带上这个参数就可以了
签名 :sm2.doSignature(msg, privateKey, { hash:true, der:true }))
验签:sm2.doVerifySignature(msg, vSign, publicKey, { hash:true, der:true })
const msg = 'hello'
const publicKey = '04ec7e40b8dfa4b14383f703ec5403b71db0ab505b9fc41f0df45a9910a307dfbd5b3c5afdd4b90d79fa0ab70d53fd88422df77e09b254a53e72b4857f74ab1da4' // 公钥
const privateKey = '58967e2beb6fffd3c96545eebd3000b39c10087d48faa0d41f9c7bf3720e0ea4' // 私钥
const verifyData=sm2.doSignature(msg, privateKey, { hash:true, der:true });
console.log(verifyData)
//这里的vsign是java生成的
const vSign = '30450220149d990885febfe0c399ac4481842a4452fb1e6a19de477ee5e5b7faac75686d022100be707161f13aacf6f5fd3a224a96faeee2309439767d4d0878bffafc8d86c6f6'
const ver2 = sm2.doVerifySignature(msg, vSign, publicKey, { hash:true, der:true })
到这儿,也就结束了 ,如果后端也有问题 让后端参考 https://github.com/ZZMarquis/gmhelper 这个人封装的国密方法
更多推荐
所有评论(0)