VUE使用 sm-crypto 加解密以及签名验签遇到的坑 (后端java)

11 篇文章 0 订阅
1 篇文章 0 订阅

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  这个人封装的国密方法

 

 

 

 

 

 

 

 

 

 

 

  • 40
    点赞
  • 65
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值