当前位置: 首页 > 工具软件 > sm-validator > 使用案例 >

js的sm-crypto和 java的bcprov-jdk16-1.46.jar 的sm2,sm3,sm4算法区别和修改

牧献
2023-12-01

目录

1.需求:

 2.关键技术

3.APP和前端网页->实现

4.Java后台->实现

5.个人使用加密后结果不一致,总结一下区别


1.需求:

·Vue网页端实现数据数据安全,关键数据加密,防篡改等
·Apk手机端实现数据安全,关键数据加密,防篡改,APK完整性校验等
·Java后台实现库
·Apk用uniApp开发,如果是java开发可以借鉴使用java库

 2.关键技术

·关键数据加密sm2
·项目数据安全防篡改sm4与sm3结合
·手机端APK完整性校验sm3自定义签名方式(计算数据快)
·js(vue,uniApp)使用sm-crypto->跳转
·java(AppJava开发,java后台)

3.APP和前端网页->实现

Vue和Uniapp前端网页sm-crypto

打开项目终端:npm install-save sm-crypto

使用:
SM2
获取密钥对

const sm2 = require('sm-crypto).sm2
let keypair = sm2.generateKeyPairHex()
publicKey=keypair.publicKey//公钥
orivateKey=keypair.privateKey//私钥
/自定义随机数,参数会直接透传给jsbn库的BigInteger构造器
/注意:开发者使用自定义随机数,需要自行确保传入的随机数符合密码学安全
let keypair2= sm2.generateKeyPairHex('123123123123123')
let keypair3= sm2.generateKeyPairHex(256,SecureRandom)
Let verifyResult=sm2.verifyPublicKey(publicKey)//验证公钥

加密解密

const sm2= require('sm-crypto').sm2
const cipherMode=1 //1-C1C3C2,0-C1c2C3,默认为1
let encryptData=sm2.doEncrypt(msgString,publicKey,.cipherMode)/加密结果
let decryptData=sm2.doDecrypt(encryptData,privateKey,cipherMode)//解密结果
 let encryptData=sm2.doEncrypt(msgArray,publicKey,cipherMode)/加密结果,输入数组
decryptData =sm2.doDecrypt(encryptData,privateKey,cipherMode,{output:'array'})//解密结果

签名验签

const sm2 = require('sm-crypto').sm2
//纯签名+生成椭圆曲线点
let sigvalueHex= sm2.dosignature(msg,privateKey)//签名
let verifyResult=sm2.doverifysignature(msg,sigValueHex,publicKey)/验签结果
//纯签名
let sigvalueHex2 sm2.dosignature(msg,privatekey,{
pointPool:[sm2.getpoint(),sm2.getPoint(),sm2.getpoint(),sm2.getPoint()],//传入事先已生成好的椭圆曲线点,可加快签名速度
})//签名
let verifyResult2=sm2.doverifysignature(msg,sigValueHex.2,publicKey)/验签结果
//纯签名+生成椭圆曲线点+der编解码
let sigvalueHex3 sm2.dosignature(msg,privatekey,
der:true,
})//签名
let verifyResult3 =sm2.doverifysignature(msg,sigvalueHex3,publickey,{
der:true,
})//验签结果
//纯签名+生成椭圆曲线点+sm3杂凑
let sigvalueHex4 sm2.dosignature(msg,privateKey,{
hash:true,
})//签名
let verifyResult4 sm2.doverifysignature(msg,sigvalueHex4,publicKey,{
hash:true,
})//验签结果

//纯签名+生成椭圆曲线点+s3杂凑(不做公钥推导)
let= sigvalueHex5 sm2.dosignature(msg,privateKey,{
hash:true,
publicKey,//传入公钥的话,可以去掉sm3杂凑中推导公钥的过程,速度会比纯签名+生成椭圆曲线点+sm3杂凑快
})
let verifyResult5 sm2.doverifysignature(msg,sigvalueHex5,publickey,
hash:true,
publicKey,
})
//纯签名+生成椭圆曲线点+sm3杂凑+不做公钥推+添加userId(长度小于8192)
//默认userId值为1234567812345678
let sigvalueHex6= sm2.dosignature(msgstring,privateKey,{
hash:true,
publicKey,
userId:'testUserId',
})
let verifyResult6 =sm2.doverifysignature(msgstring,sigvalueHex6,publicKey,{
hash:true,
userId:'testUserId',
})

获取椭圆曲线点

const sm2 =require('sm-crypto').sm2
let point=sm2.getPoint()//获取一个椭圆曲线点,可在sm2签名时传入

SM3

const sm3 =require('sm-crypto').sm3
let hashData=sm3('abc')//杂凑

SM4

加密

const sm4 =require('sm-crypto').sm4
const msg='hel1o world!我是juneandgreen.'//可以为utf8串或字节数组
const key='0123456789 abcdeffedcba9876543210'//可以为16进制串或字节数组,要求为128比特
let encryptData=sm4.encrypt(msg,key)/加密,默认输出I6进制字符串,默认使用pkcs#7填充(传pkcs#5 也会走 pkcs#7 填充)
let encryptData=sm4.encrypt(msg,key,[padding:'none'})/加密,不使用padding
let encryptData=sm4.encrypt(msg,key,{padding:'none',output:'array'})//加,不使用padding,输出为字节数组
let encryptData= sm4.encrypt(msg,key,{mode:'cbc',iv:'fedcba98765432100123456789abcdef'})//加密,abc模式

 解密 

const sm4 =require('sm-crypto').sm4
const encryptData ='0e395deb10f6e8a17e17823e1fd9bd98a1bff1df508b5b8alefb79ec633d1bb129432ac1b74972deb97bab04f024e89c'//可以为16进制串或字节数组
const key='0123456789 abcdeffedcba9876543210'//可以为16进制串或字节数组,要求为128比特
Let decryptData=sm4.decrypt(encryptData,key)//解密,默认输出utf8字符串,默认使用pkcs#7填充(传 pkcs#5 也会走pkcs#7 填充)
Let decryptData=sm4.decrypt(encryptData,key,{padding:'none'})//解密,不使用padding
Let decryptData=sm4.decrypt(encryptData,key,{padding:'none',output:'array'})/解,不使用
padding,输出为字节数组
Let decryptData= sm4.decrypt(encryptData,key,{mode:'cbc',iv:'fedcba98765432100123456789abcdef'})//解密,cbc模式

4.Java后台->实现

java使用BC库bcprov-jdk16-1.46.jar,例子可以网上查一下

5.个人使用加密后结果不一致,总结一下区别

sm2java加密后的串,对比js结果多了一个'04'字符,所以js在使用的时候需要去掉04字符,
同理js加密的串对比java少了'04',所以火java使用的时候需要加上字符
sm3加密串一致
sm4前提是java sm4加密都设置padding=true,而js设置的oadding不为'none',那么加密
串不一致,需要看一下,js和java不满16位补位问题,而在我的项目中目前版本,java的补
位是0,而js的补位是不满16位,剩余个数(16-不满16位个数),将其改为0即可

 类似资料: