国密算法基础:SM2、SM3、SM4 与国际算法对比
这一章,我们来啃国密算法的核心。SM2、SM3、SM4,这三个名字你肯定不陌生。但说实话,很多人只是知道个名字,真要讲清楚它们怎么工作的、跟 RSA/AES/SHA-256 比到底差在哪,就含糊了。
我当年刚接触国密改造时,也踩过不少坑。有一次在项目中,客户要求用 SM2 替换 RSA,结果我直接把 RSA 的密钥对格式套给了 SM2,导致签名验签死活通不过。后来才发现,SM2 的密钥结构跟 RSA 完全不一样。嗯,这种细节,咱们今天一次性说透。
SM2 非对称算法:原理与对比
SM2 是基于椭圆曲线密码学(ECC)的。它用的是一条特定的 256 位椭圆曲线,参数由国家密码管理局定义。说白了,它的安全性依赖于椭圆曲线上的离散对数难题——给你一个点 P 和倍数 k,求 kP 很容易,但给你 P 和 kP,反推 k 几乎不可能。
核心要点:SM2 的密钥长度是 256 位,但安全强度相当于 3072 位的 RSA。这意味着什么?同样的安全等级,SM2 的密钥更短、计算更快、存储更省。
我个人的习惯是,在移动端或 IoT 设备上优先考虑 SM2。为什么?因为资源受限,SM2 的轻量级优势非常明显。
| 对比项 | SM2 | RSA-2048 |
|---|---|---|
| 算法基础 | 椭圆曲线(ECC) | 大整数分解 |
| 密钥长度 | 256 位 | 2048 位 |
| 安全强度 | ≈ RSA-3072 | 标准 112 位 |
| 签名速度 | 快 | 慢 |
| 验签速度 | 较快 | 快 |
| 密钥生成 | 极快 | 慢 |
你想想看,RSA 的密钥生成需要找两个大素数,这个过程很耗时。而 SM2 只需要随机选一个标量 k,然后计算 kP 就行。我在项目中做过测试,SM2 密钥生成比 RSA 快了两个数量级。
避坑指南:我曾经在对接某硬件加密机时,发现 SM2 的签名结果格式跟国际标准不一样。SM2 的签名是 (r, s) 两个大整数,但有些库会把它编码成 DER 格式,有些则是纯字节拼接。一定要确认好对方的编码方式,否则验签必败。
SM3 密码杂凑算法:原理与对比
SM3 是国密标准的哈希算法,输出 256 位的摘要值。它的结构跟 SHA-256 非常像,都是 Merkle-Damgård 结构,消息分组处理,每轮 64 步迭代。
但细节上有差异。SM3 的压缩函数用了更多的异或、循环移位和布尔函数,设计上更保守,安全性余量更高。我记得有篇论文分析过,SM3 的抗碰撞能力比 SHA-256 还要强一些。
| 对比项 | SM3 | SHA-256 |
|---|---|---|
| 输出长度 | 256 位 | 256 位 |
| 结构 | Merkle-Damgård | Merkle-Damgård |
| 轮数 | 64 轮 | 64 轮 |
| 消息分组 | 512 位 | 512 位 |
| 安全强度 | 128 位 | 128 位 |
| 性能 | 略慢于 SHA-256 | 较快 |
实际项目中,SM3 的性能比 SHA-256 慢大约 10%-20%。但说实话,这个差距在大多数场景下可以忽略。除非你在做高并发的哈希计算,比如每秒几万次,否则感受不到。
注意:SM3 和 SHA-256 的摘要值长度都是 32 字节,但内容完全不同。不要试图在 SM3 的摘要上直接套用 SHA-256 的签名逻辑。我曾经见过有人把 SM3 摘要当 SHA-256 用,结果签名验签全乱套。
SM4 对称分组密码:原理与对比
SM4 是国密标准的对称分组密码算法,分组长度 128 位,密钥长度也是 128 位。它的结构是 Feistel 网络,跟 AES 的 SPN 结构不同。
SM4 的轮数是 32 轮,每轮使用一个轮密钥。轮密钥由密钥扩展算法生成,这个扩展算法本身也是类似 Feistel 的结构。我个人觉得,SM4 的设计非常精巧,硬件实现起来特别高效。
| 对比项 | SM4 | AES-128 |
|---|---|---|
| 分组长度 | 128 位 | 128 位 |
| 密钥长度 | 128 位 | 128 位 |
| 结构 | Feistel 网络 | SPN 结构 |
| 轮数 | 32 轮 | 10 轮 |
| 加解密速度 | 较快 | 快 |
| 硬件实现 | 非常高效 | 高效 |
你可能会问,SM4 轮数比 AES 多这么多,是不是更慢?其实不然。Feistel 结构的每一轮计算量比 SPN 小,所以 32 轮的总计算量跟 AES 的 10 轮差不多。我在嵌入式设备上测试过,SM4 的加解密速度跟 AES-128 基本持平。
实战经验:SM4 支持多种工作模式,比如 ECB、CBC、CTR、GCM。我建议优先使用 GCM 模式,因为它同时提供加密和认证,能防止密文被篡改。ECB 模式千万别用,它会把相同的明文块加密成相同的密文块,泄露模式信息。
三种国密算法的关系与典型应用
在实际系统中,SM2、SM3、SM4 经常配合使用。比如一个典型的国密 TLS 握手过程:
- 用 SM2 做密钥交换和身份认证
- 用 SM3 做消息摘要和完整性校验
- 用 SM4 做会话数据的对称加密
这种组合,既利用了非对称算法的密钥分发能力,又发挥了对称算法的高效性能,再加上哈希算法的完整性保护,形成了一个完整的安全体系。
一句话总结:SM2 管密钥分发和签名,SM4 管数据加密,SM3 管完整性校验。三者缺一不可。
下面这张图展示了它们之间的关系:
国密改造中的常见误区
最后,我总结几个我在项目中反复遇到的坑:
- 密钥格式不兼容:SM2 的密钥对是 (d, P),d 是私钥(256 位),P 是公钥(两个 256 位坐标)。跟 RSA 的 (n, e, d) 结构完全不同。别想着直接转换格式。
- 签名编码不一致:SM2 签名结果 (r, s) 的编码方式,有的库用 DER,有的用纯字节。对接前一定要确认。
- 哈希长度误用:SM3 输出 32 字节,SHA-256 也是 32 字节,但内容不同。不要混用。
- 工作模式选择:SM4 的 ECB 模式不安全,GCM 模式推荐。CTR 模式也可以,但需要额外处理消息认证。
- 性能预估偏差:SM2 签名比 RSA 快,但验签不一定。SM3 比 SHA-256 慢一点,但差距不大。SM4 跟 AES 性能相当。
重要提醒:国密算法是国家标准,但不同厂商的实现可能有细微差异。比如 SM2 的曲线参数、SM4 的 S 盒,虽然标准是统一的,但有些库在边界条件处理上不一样。我建议在项目初期就做好多厂商的交叉测试,避免后期集成时出问题。