sm-crypto:SM算法的JavaScript实现

先在项目目录下安装 npm install --save sm-crypto

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

/**
 * sm2生成密钥对
 */
let keypair = sm2.generateKeyPairHex()

publicKey = keypair.publicKey // 公钥
privateKey = keypair.privateKey // 私钥

console.log("pk : %s", publicKey);
console.log("sk : %s", 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) // 验证公钥
console.log(verifyResult);
verifyResult = sm2.verifyPublicKey(compressedPublicKey) // 验证公钥
console.log(verifyResult);

/**
 * sm2加密解密
 */

const cipherMode = 1 // 1 - C1C3C2,0 - C1C2C3,默认为1
let msgString = "肥兔子爱豆畜子";
let encryptData = sm2.doEncrypt(msgString, publicKey, cipherMode) // 加密结果
console.log("sm2加密结果 %s", encryptData);
let decryptData = sm2.doDecrypt(encryptData, privateKey, cipherMode) // 解密结果
console.log("sm2解密结果 %s", decryptData);

//encryptData = sm2.doEncrypt(msgArray, publicKey, cipherMode) // 加密结果,输入数组
//decryptData = sm2.doDecrypt(encryptData, privateKey, cipherMode, {output: 'array'}) // 解密结果,输出数组

/**
 * sm3 摘要算法 与hmac
 */
const sm3 = require('sm-crypto').sm3

let hashData = sm3("肥兔子爱豆畜子");

// hmac
hashData = sm3("肥兔子爱豆畜子", {
    key: 'daac25c1512fe50f79b0e4526b93f5c0e1460cef40b6dd44af13caec62e8c60e0d885f3c6d6fb51e530889e6fd4ac743a6d332e68a0f2a3923f42585dceb93e9', // 要求为 16 进制串或字节数组
});

/**
 * sm4对称加密解密
 */
const sm4 = require('sm-crypto').sm4
const msg = '肥兔子爱豆畜子' // 可以为 utf8 串或字节数组
const key = '0123456789abcdeffedcba9876543210' // 对称密钥,可以为 16 进制串或字节数组,要求为 128 比特

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 模式
console.log("sm4加密结果 %s", encryptData);
 
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 模式
console.log("sm4解密结果 %s", decryptData);

运行node sm.js
运行结果:

node .\sm.js
pk : 04cc7213c14baefaaaa6c26f40f33835b64fb75c1a32a75cc13de3fae98de82f0e789948a2175613741d67e3930dadc25fcde04e8548fc834f5b4f8e2a0956f32b
sk : 02ab785c7b474d023a400ecb4d814a457e5d46a62bedf208b7d3508dea0bd007
true
true
sm2加密结果 e8c2412f6b0bba8a3a711904eb8a369d1aac4b1e4f9322502018a3980ae37a7f35fa373f055ee24d6ce6fd6ce78f9a57293837553cd24df84a29ea86a1e1d7fa624fdbc78fdf50ec556ab246e0a9880a3d0b9dccb1cd8295ab054e9248218dd61a8e6c837700e37013e3f84a151d4fbd2516332ea4
sm2解密结果 肥兔子爱豆畜子
sm4加密结果 594f3d28edd3f59e56c1931e0a639252c99b7c77cf0bac4016193b81ea60052f
sm4解密结果 肥兔子爱豆畜子
sm3与hmac

sm3(msg) 相当于是对msg做了摘要或者说指纹
sm3(msg, key) key是个secret,在摘要基础上做了身份认证,比如请求后面可以用sm2Sign(请求内容, sk)签名的方式来鉴别身份+保证完整性,也可以hmac这种方式同样能够鉴别身份+保证完整性。

参考

https://github.com/JuneAndGreen/sm-crypto

posted on   肥兔子爱豆畜子  阅读(27)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示