当前位置: 代码网 > it编程>编程语言>Javascript > 使用JS前端加密库sm-crypto实现国密sm2、sm3和sm4加密与解密

使用JS前端加密库sm-crypto实现国密sm2、sm3和sm4加密与解密

2024年06月11日 Javascript 我要评论
国密sm2、sm3、sm4的js使用国密算法sm2、sm3和sm4的js实现。安装 sm-cryptonpm install --save sm-cryptojs国密sm2加密获取密钥对const s

国密sm2、sm3、sm4的js使用

国密算法sm2、sm3和sm4的js实现。

安装 sm-crypto

npm install --save sm-crypto

js国密sm2加密

获取密钥对

const sm2 = require('sm-crypto').sm2

let keypair = sm2.generatekeypairhex()

publickey = keypair.publickey // 公钥
privatekey = keypair.privatekey // 私钥

// 默认生成公钥 130 位太长,可以压缩公钥到 66 位
const compressedpublickey = sm2.compresspublickeyhex(publickey) // compressedpublickey 和 publickey 等价
sm2.comparepublickeyhex(publickey, compressedpublickey) // 判断公钥是否等价

// 自定义随机数,参数会直接透传给 jsbn 库的 biginteger 构造器
// 注意:开发者使用自定义随机数,需要自行确保传入的随机数符合密码学安全
let keypair2 = sm2.generatekeypairhex('123123123123123')
let keypair3 = sm2.generatekeypairhex(256, securerandom)

let verifyresult = sm2.verifypublickey(publickey) // 验证公钥
verifyresult = sm2.verifypublickey(compressedpublickey) // 验证公钥

加密解密

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) // 解密结果

encryptdata = sm2.doencrypt(msgarray, publickey, ciphermode) // 加密结果,输入数组
decryptdata = sm2.dodecrypt(encryptdata, privatekey, ciphermode, {output: 'array'}) // 解密结果,输出数组

ps:密文会在解密时自动补充 04,如遇到其他工具补充的 04 需手动去除再传入。

签名验签

ps:理论上来说,只做纯签名是最快的。

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, sigvaluehex2, 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,
}) // 验签结果

// 纯签名 + 生成椭圆曲线点 + sm3杂凑(不做公钥推导)
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签名时传入

根据私钥获取公钥

const sm2 = require('sm-crypto).sm2

let publickey = sm2.getpublickeyfromprivatekey(privatekey)

js国密sm3加密

const sm3 = require('sm-crypto').sm3

let hashdata = sm3('abc') // 杂凑

// hmac
hashdata = sm3('abc', {
    key: 'daac25c1512fe50f79b0e4526b93f5c0e1460cef40b6dd44af13caec62e8c60e0d885f3c6d6fb51e530889e6fd4ac743a6d332e68a0f2a3923f42585dceb93e9', // 要求为 16 进制串或字节数组
})

js国密sm4加密

加密

const sm4 = require('sm-crypto').sm4
const msg = 'hello world! 我是 juneandgreen.' // 可以为 utf8 串或字节数组
const key = '0123456789abcdeffedcba9876543210' // 可以为 16 进制串或字节数组,要求为 128 比特

let encryptdata = sm4.encrypt(msg, key) // 加密,默认输出 16 进制字符串,默认使用 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'}) // 加密,cbc 模式

解密

const sm4 = require('sm-crypto').sm4
const encryptdata = '0e395deb10f6e8a17e17823e1fd9bd98a1bff1df508b5b8a1efb79ec633d1bb129432ac1b74972dbe97bab04f024e89c' // 可以为 16 进制串或字节数组
const key = '0123456789abcdeffedcba9876543210' // 可以为 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 模式

以上就是使用js前端加密库sm-crypto实现国密sm2、sm3和sm4加密与解密的详细内容,更多关于js国密sm2、sm3和sm4加密与解密的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com