🚀 sm-crypto 全面升级:国密算法库性能提升 25 倍的秘密
摘要:从 JavaScript 到 TypeScript,从 jsbn 到原生 BigInt,sm-crypto-v2 如何在不破坏 API 兼容性的前提下,实现国密算法性能的质的飞跃?本文将深度解析两代库的核心差异,并给出选型建议。
一、背景:国密算法的前端之路
在金融、政务等关键领域,国密算法(SM2/SM3/SM4) 已成为合规标配。中办 2018 年 36 号文件明确要求,金融、电子政务、教育等领域必须全面推进自主可控密码技术的应用 。
对于前端开发者而言,sm-crypto 一直是 JavaScript 生态中国密算法的事实标准。但随着业务对性能要求的不断提升,原版基于 jsbn(JavaScript Big Number)的实现逐渐暴露出性能瓶颈:
- SM2 签名验签慢:在移动端设备上尤为明显
- 缺乏类型支持:TypeScript 项目需要额外声明文件
- 包体积较大:jsbn 依赖增加了不必要的体积
- 随机数安全:使用
Math.random()存在潜在风险
于是,sm-crypto-v2 应运而生。

二、架构重构:从底层开始的革新
2.1 大数运算的范式转移
sm-crypto (原版)
// 依赖 jsbn 库进行大数运算
const BigInteger = require('jsbn').BigInteger;
// 所有椭圆曲线运算都基于 jsbn
sm-crypto-v2
// 原生 BigInt 支持,无需第三方依赖
const k = BigInt('0x' + privateKey);
// 基于 noble-curves 抽象层重构 SM2
核心改进:
- 完全移除
jsbn依赖,包体积从 未压缩 34kb → 压缩后仅 17kb - 自动选择最优随机数实现,告别
Math.random()和Date.now()的临时方案
2.2 现代模块系统的拥抱
// sm-crypto-v2 同时支持 ESM 和 CJS
import { sm2 } from 'sm-crypto-v2'; // ES Module ✅
const { sm2 } = require('sm-crypto-v2'); // CommonJS ✅
三、性能实测:数字说话
在 Apple M2 芯片环境下进行的基准测试(使用 benchmark.js):
| 操作 | sm-crypto | sm-crypto-v2 | 性能提升 |
|---|---|---|---|
| SM2 生成密钥对 | 148 ops/sec | 3,452 ops/sec | 23.3x 🚀 |
| SM2 签名 | 150 ops/sec | 3,829 ops/sec | 25.5x 🚀 |
| SM2 验签 | 76 ops/sec | 306 ops/sec | 4x |
| SM2 加密 | 76 ops/sec | 304 ops/sec | 4x |
| SM3 Hash | 322 ops/sec | 519 ops/sec | 1.6x |
| SM3 HMAC | 244 ops/sec | 518 ops/sec | 2.1x |
| SM4 解密 | 143,430 ops/sec | 237,247 ops/sec | 1.7x |
关键发现:
- SM2 运算 是最大赢家,得益于 noble-curves 的优化实现
- 内存占用 减少 11.3MB,运行结束后垃圾回收更彻底
- SM4 本身已接近硬件极限,提升相对温和
四、功能增强:不只是性能
4.1 新增 API
// 1. SM2 密钥交换(ECDHE)
const { sm2 } = require('sm-crypto-v2');
const keyPair = sm2.generateKeyPairHex();
const sharedSecret = sm2.computeSharedSecret(
keyPair.privateKey,
otherPublicKey
);
// 2. SM4 GCM 模式(提供认证加密)
const { sm4 } = require('sm-crypto-v2');
const encrypted = sm4.encryptGCM(plaintext, key, iv, aad);
const decrypted = sm4.decryptGCM(encrypted, key, iv, aad, tag);
4.2 类型安全
// sm-crypto-v2 提供完整的 TypeScript 类型定义
import { sm2, sm3, sm4 } from 'sm-crypto-v2';
// 类型提示和检查
const cipherMode: number = 1; // 1 = C1C2C3, 0 = C1C3C2
const signature: string = sm2.doSignature(msg, privateKey, {
cipherMode,
hash: true,
der: true
});
五、实战迁移指南
5.1 安装升级
# 原版(维护模式)
npm install sm-crypto
# 新版(推荐)
npm install sm-crypto-v2
5.2 代码兼容
好消息:sm-crypto-v2 完全兼容原版 API,历史单元测试全部通过!
// 以下代码在两个版本中完全一致
const { sm2, sm3, sm4 } = require('sm-crypto-v2');
// SM2 签名验签
let sigValueHex = sm2.doSignature(msg, privateKey, {
hash: true,
der: true
});
let verifyResult = sm2.doVerifySignature(msg, sigValueHex, publicKey, {
der: true
});
// SM3 哈希
const hash = sm3(msg);
// SM4 加密(CBC模式)
const encryptData = sm4.encrypt(msg, key, { mode: 'cbc', iv });
5.3 何时升级?
| 场景 | 建议 |
|---|---|
| 新项目 | ✅ 直接使用 sm-crypto-v2 |
| 使用 TypeScript | ✅ 升级以获得完整类型支持 |
| SM2 运算性能瓶颈 | ✅ 升级可获 20x+ 性能提升 |
| 需要 SM4 GCM 模式 | ✅ v2 独有功能 |
| 老项目稳定运行 | 可暂不升级,但建议规划迁移 |
| 对包体积极度敏感 | ✅ v2 体积更小 |
六、应用场景:国密算法在金融科技中的实践
根据央行《金融领域密码应用指导意见》,支付系统需在 2025 年前完成国密改造 。以下是典型应用场景:
6.1 网银支付 - SM2 数字签名
- 前端使用 SM2 私钥对交易指令签名
- 后端验签确保交易不可否认性
6.2 用户认证 - SM3 密码哈希
- 前端 SM3(msg + salt) 处理密码
- 防御彩虹表攻击,符合等保 2.0
6.3 数据传输 - SM4 通道加密
- 结合国密 SSL 证书(SM2 + SM4 + SM3)
- 替代传统 RSA/AES 方案
七、技术细节:为什么 BigInt 更快?
jsbn 的局限:
- 纯 JavaScript 实现的大数库
- 使用数组存储数字位,运算需要循环遍历
- 每个操作都有函数调用开销
原生 BigInt 的优势:
- 引擎级优化:V8 等引擎针对 BigInt 进行专门优化
- 内存布局:连续内存存储,CPU 缓存友好
- 算法优化:底层使用更快的乘法/模幂算法
此外,sm-crypto-v2 的 SM2 实现基于 noble-curves 库的 Abstract API,该库是密码学领域的现代标杆实现,经过形式化验证和广泛审计。
八、总结与展望
| 维度 | sm-crypto | sm-crypto-v2 |
|---|---|---|
| 语言 | JavaScript | TypeScript |
| 底层实现 | jsbn | 原生 BigInt + noble-curves |
| 性能 | 基准 | SM2 提升 25x,整体显著提升 |
| 包体积 | 较大 | 17kb (压缩后) |
| 模块系统 | CommonJS | ESM + CJS 双支持 |
| 新特性 | 基础功能 | SM2 密钥交换、SM4 GCM |
| 维护状态 | 维护模式 | 积极开发中 |
选型建议:
- 新项目:无脑选
sm-crypto-v2,更好的性能 + 类型安全 - 存量项目:评估 SM2 使用场景的性能压力,适时升级
- 合规项目:两个版本均通过国家密码标准测试,均可放心使用
随着国产自主可控战略的推进,国密算法在前端生态中的地位将越来越重要。sm-crypto-v2 的出现,不仅是一次性能升级,更是国密算法库现代化的重要里程碑。
参考链接
💡 提示:如果你在使用过程中遇到问题,欢迎在评论区交流。对于 SM2 性能优化、SM4 GCM 模式使用等话题,后续可以单独开篇详聊。