
国密算法(SM系列)详解与实战:从原理到应用
随着网络安全法和等保 2.0 的实施,国密算法(National Secret Algorithms)在金融、政务、物联网等领域的应用已成为合规的标配。本文将深入探讨 SM2、SM3、SM4 等核心算法的技术原理,对比国际标准算法,并提供详细的 Node.js 实战指南。
1. 国密算法背景
国密算法是由中国国家密码管理局发布的密码算法标准,旨在摆脱对国外密码技术的依赖,保障国家信息安全。
为什么需要国密?
- 自主可控:避免算法后门和潜在的安全漏洞。
- 合规要求:金融、政务等关键基础设施必须使用国密算法。
- 性能优势:部分国密算法(如 SM2)在同等安全强度下,性能优于国际标准算法。
2. 核心算法深度解析
2.1 SM2:椭圆曲线公钥密码算法
SM2 是一种基于椭圆曲线密码(ECC)的非对称加密算法。
- 原理:基于椭圆曲线离散对数问题(ECDLP)。
- 密钥长度:推荐使用 256 位。
- 安全性:SM2-256 的安全强度相当于 RSA-2048 到 RSA-3072 之间,但密钥长度远小于 RSA。
- 功能:
- 数字签名:用于身份认证和数据完整性保护。
- 密钥交换:用于通信双方协商会话密钥。
- 公钥加密:用于数据加密传输。
SM2 vs RSA:
| 特性 | SM2 (256位) | RSA (2048位) |
|---|---|---|
| 算法结构 | ECC | 大数分解 |
| 密钥生成速度 | 快 (100倍+) | 慢 |
| 加解密速度 | 快 | 解密慢 |
| 签名速度 | 快 | 验签快 |
| 密文长度 | 短 | 长 |
2.2 SM3:密码杂凑算法
SM3 是一种密码杂凑(Hash)算法,用于生成消息摘要。
- 输出长度:256 位(32 字节)。
- 结构:Merkle-Damgård 结构。
- 安全性:抗碰撞性优于 MD5 和 SHA-1,与 SHA-256 相当,但设计上针对特定攻击进行了优化。
应用场景:
- 用户密码存储(加盐 Hash)
- 文件完整性校验
- 数字签名中的摘要生成
2.3 SM4:分组密码算法
SM4 是一种分组密码算法(对称加密),原名 SMS4,最初用于无线局域网 WAPI 标准。
- 分组长度:128 位(16 字节)。
- 密钥长度:128 位。
- 轮数:32 轮非线性迭代。
- 安全性:与 AES-128 相当。
SM4 vs AES:
| 特性 | SM4 | AES |
|---|---|---|
| 密钥长度 | 128位 | 128/192/256位 |
| 分组长度 | 128位 | 128位 |
| 结构 | 非平衡 Feistel | SP 网络 |
| 效率 | 软硬件实现均高效 | 极高 (有指令集支持) |
3. 实战:Node.js 中使用 sm-crypto
我们将使用 sm-crypto 库来演示如何在 Node.js 环境中实现国密算法。
3.1 环境准备
1 | npm install sm-crypto --save |
3.2 SM2 非对称加密实战
SM2 加密时需要注意加密模式。sm-crypto 支持 C1C3C2 (默认) 和 C1C2C3 两种模式。前端与后端交互时,务必确认使用的模式一致。
1 | const sm2 = require('sm-crypto').sm2 |
3.3 SM3 摘要计算实战
SM3 常用于计算数据的指纹。
1 | const sm3 = require('sm-crypto').sm3 |
3.4 SM4 对称加密实战
SM4 适合对大量数据进行加密。注意密钥必须是 128 位(16 字节,即 32 位 hex 字符串)。
1 | const sm4 = require('sm-crypto').sm4 |
4. 常见问题与坑
- 密钥格式:SM2 公钥通常是
04开头的 130 位 Hex 字符串(未压缩),私钥是 64 位 Hex。如果遇到 PEM 格式,需要进行转换。 - 加密模式:SM2 的密文排序有 C1C2C3 和 C1C3C2 两种标准。旧标准多用 C1C2C3,新标准(及 OpenSSL 1.1.1+)多用 C1C3C2。对接时一定要确认。
- 性能:在纯 JS 环境下,SM2 的性能可能不如原生 C++ 实现的模块。对于高并发场景,建议使用基于 OpenSSL 或 C++ 扩展的库(如
gm-crypto)。
5. 总结
掌握国密算法是国内开发者的必备技能。通过 sm-crypto,我们可以轻松地在 Node.js 和浏览器端实现 SM2/SM3/SM4。在实际项目中,建议结合 HTTPS 使用,构建多层纵深防御体系。
本文是原创文章,采用CC BY-NC-SA 4.0协议,完整转载请注明来自码海拾贝







