告别CryptoJS!用sm-crypto在Node.js和浏览器里轻松搞定国密SM2/SM3/SM4
告别CryptoJS用sm-crypto在Node.js和浏览器里轻松搞定国密SM2/SM3/SM4国密算法作为我国自主研发的密码标准体系正在金融、政务、物联网等领域加速普及。然而对于长期使用CryptoJS等国际通用加密库的开发者来说切换到国密算法往往意味着要面对API差异、环境适配等一系列挑战。本文将带你用sm-crypto这个轻量级工具库在Node.js和浏览器环境中无缝实现国密算法的加解密、签名验签全流程。1. 为什么选择sm-crypto进行国密算法开发在合规要求日益严格的今天许多项目不得不从国际通用加密标准转向国密算法。传统方案通常需要为浏览器和Node.js环境分别选择不同的库而sm-crypto的出现完美解决了这个痛点。核心优势对比特性sm-crypto传统方案组合跨环境支持同一API在浏览器/Node运行需要不同库分别实现算法完整性完整支持SM2/SM3/SM4可能需要多个库组合包体积仅86KB(minified)组合后通常超过200KB开发体验一致的TypeScript类型定义各库类型定义可能冲突实际项目中我们遇到过CryptoJS迁移到国密算法的典型场景某金融App需要在前端实现SM2签名在后端用Node.js验证签名。使用sm-crypto后前后端代码相似度达到90%以上大幅降低了维护成本。2. 五分钟快速上手SM3哈希算法SM3作为国密标准中的密码杂凑算法常用于数据完整性校验。与SHA-256相比SM3在相同安全强度下具有更好的国产化合规特性。基础使用示例// 在Node.js环境 const smCrypto require(sm-crypto); const hash smCrypto.sm3(需要哈希的原始数据); // 在浏览器环境通过Webpack等打包工具 import { sm3 } from sm-crypto; const hash sm3(需要哈希的原始数据);进阶技巧处理大型文件时建议使用流式处理结合Web Worker避免主线程阻塞与Base64编码配合使用更易存储注意SM3输出的哈希值为32字节(256位)通常表示为64个字符的16进制字符串3. SM4对称加密实战从配置到优化SM4作为国密标准的对称加密算法其128位分组大小和安全性对标国际上的AES算法。以下是典型的使用场景实现const key 0123456789ABCDEF; // 16字节密钥 const iv ABCDEF0123456789; // 16字节初始向量 // CBC模式加密示例 const encrypted sm4.encrypt(敏感数据, key, { mode: cbc, iv: iv, padding: pkcs7 }); // 解密过程 const decrypted sm4.decrypt(encrypted, key, { mode: cbc, iv: iv, padding: pkcs7 });性能优化建议对于大量数据加密优先选择ECB模式无IV需求在Web环境中使用WebCrypto API进行硬件加速缓存密钥对象避免重复解析4. SM2非对称加密全流程解析SM2基于椭圆曲线密码学相比RSA在相同安全强度下密钥更短、计算更快。下面是完整的密钥生成、加密、签名流程密钥对生成const { publicKey, privateKey } sm2.generateKeyPairHex(); // 典型输出 // publicKey: 04... (130字符16进制) // privateKey: ... (64字符16进制)数据加密与解密// 使用公钥加密 const ciphertext sm2.doEncrypt(机密消息, publicKey, 1); // 使用私钥解密 const plaintext sm2.doDecrypt(ciphertext, privateKey, 1);数字签名与验证// 生成签名 const sig sm2.doSignature(重要文件, privateKey); // 验证签名 const isValid sm2.doVerifySignature(重要文件, sig, publicKey);常见问题解决方案遇到publicKey is invalid错误时检查公钥是否包含04前缀签名验证失败时确认双方使用的userId参数是否一致大文件签名建议先计算SM3哈希再对哈希值签名5. 跨环境构建的最佳实践实现一套代码在浏览器和Node.js环境同时运行需要解决模块系统和依赖管理的差异。以下是经过实战验证的方案Webpack配置示例// webpack.config.js module.exports { resolve: { fallback: { crypto: require.resolve(crypto-browserify), stream: require.resolve(stream-browserify) } } }Rollup用户需要注意// rollup.config.js import nodeResolve from rollup/plugin-node-resolve; export default { plugins: [ nodeResolve({ browser: true, preferBuiltins: false }) ] }TypeScript类型定义技巧// global.d.ts declare module sm-crypto { export function sm3(message: string): string; export const sm4: { encrypt: (input: string, key: string, options?: object) string; decrypt: (input: string, key: string, options?: object) string; }; // 其他类型定义... }在Vue/React项目中建议将加密操作封装为自定义Hook或Composable Function便于统一管理密钥和算法参数。