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这种方式同样能够鉴别身份+保证完整性。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构