2. 国密与常见国际密码算法对比(SM2 vs RSA,SM3 vs SHA-256,SM4 vs AES)
2.1 为什么我们要做这个对比?
说实话,很多开发者第一次接触国密时,心里都在犯嘀咕:“不就是换个算法嘛,能有多大区别?”
我刚开始接手国密改造项目时也这么想。结果第一周就被 SM2 的密钥格式整懵了——跟 RSA 完全不是一回事。嗯,后来我才意识到,要是不把这些差异摸透,后面踩坑就是家常便饭。
这一章,我把三组算法掰开揉碎给你讲清楚:
- SM2 vs RSA —— 公钥密码体系,一个椭圆曲线,一个大整数分解
- SM3 vs SHA-256 —— 哈希函数,结构相似但细节不同
- SM4 vs AES —— 对称分组密码,算法骨架几乎一个模子
2.2 整体对比框架
先看一张图,把三组的脉络理清。
2.3 SM2 vs RSA —— 椭圆曲线 vs 大整数分解
SM2 跟 RSA 都是公钥密码,但底层数学完全不同。RSA 靠大整数分解的困难性,SM2 靠椭圆曲线离散对数问题。
我个人习惯先说结论:SM2 在同等安全强度下,密钥长度短得多,运算速度快得多。你想想看,RSA 2048 位的密钥在嵌入式设备上要做一次私钥操作,动辄几十毫秒,而 SM2 只要几百微秒——差了一个数量级。
| 对比项 | SM2 | RSA |
|---|---|---|
| 底层数学难题 | 椭圆曲线离散对数 | 大整数分解 |
| 密钥长度(位) | 256 | 2048 / 3072 / 4096 |
| 签名性能(倍) | 约 10x 快 | 基准 |
| 加密/解密性能 | 加密慢,解密快 | 加密快,解密慢 |
| 密文膨胀 | 小(密钥点 + hash) | 大(模数长度) |
| 标准文档 | GM/T 0003-2012 | PKCS#1 / RFC 8017 |
我在项目中遇到过一个问题:把 RSA 2048 的密钥对直接当成 SM2 密钥对导入硬件安全模块(HSM),结果报错。因为 SM2 的私钥是一个 256 位的随机数,而 RSA 私钥是两个大素数。嗯,这里要注意——千万别用 RSA 的密钥格式去解析 SM2。
2.4 SM3 vs SHA-256 —— 结构近似,细节不同
SM3 和 SHA-256 都属于 Merkle-Damgård 结构。说实话,第一次看 SM3 规范时我觉得它在抄 SHA-256,但仔细一对比,发现轮函数、常量、消息扩展全部不一样。
我给你们看一组核心差异:
| 特性 | SM3 | SHA-256 |
|---|---|---|
| 输出长度 | 256 位 | 256 位 |
| 分组长度 | 512 位 | 512 位 |
| 轮数 | 64 轮 | 64 轮 |
| 消息扩展 | W[j] 依赖 W[j-16] 等(类似 SHA-1) | W[j] 依赖 σ0、σ1 |
| 压缩函数 | 使用 16 个 32 位寄存器(A~H、A'~H') | 使用 8 个 32 位寄存器(A~H) |
| 布尔函数 | FF、GG 有 2 个变体(j<16 和 j≥16) | Ch、Maj 固定 |
| 国密规范 | GM/T 0004-2012 | FIPS PUB 180-4 |
2.5 SM4 vs AES —— 对称密码的“表兄弟”
SM4 是中国商密标准里的 分组密码,分组长度 128 位,密钥长度 128 位。AES 分组长度也是 128 位,但密钥支持 128/192/256 位。结构上,SM4 是 Feistel 网络(32 轮),AES 是 SPN 结构(10/12/14 轮)。
你可能会问:“Feistel 和 SPN 哪个好?” 说实话,各有千秋。Feistel 的加解密结构对称,实现简单;SPN 在硬件上更容易并行,速度更快。但对我们做 SDK 接入的人来说,关心的是 调用的接口长什么样。
// 伪代码示意
class CipherSM4 : public Cipher {
void encrypt(const uint8_t* plain, size_t len,
const uint8_t* key, const uint8_t* iv,
Mode mode) override;
void decrypt(const uint8_t* cipher, size_t len,
const uint8_t* key, const uint8_t* iv,
Mode mode) override;
};
SM4 和 AES 的另一个显著区别是 S 盒。两者都是 8×8 的替换表,但值完全不一样。如果你自己实现密码库,千万别把 AES 的 S 盒拿来当 SM4 的用——我曾经见过有人这么干,结果加解密全部错误。
2.6 性能对比快照
下面这张表是我在某个 x86 服务器上跑基准测试得到的近似值(OpenSSL 1.1.1 + 国密模块)。当然,不同硬件和实现会有差异,但趋势是稳定的。
| 算法 | 操作 | 吞吐量(MB/s) | 一次操作耗时(微秒) |
|---|---|---|---|
| SM2 | 签名 | - | ~120 |
| RSA 2048 | 签名 | - | ~1100 |
| SM2 | 验签 | - | ~60 |
| RSA 2048 | 验签 | - | ~30 |
| SM3 | 哈希 | ~550 | - |
| SHA-256 | 哈希 | ~620 | - |
| SM4-CBC | 加密 | ~480 | - |
| AES-128-CBC | 加密 | ~680 | - |
从数据来看,SM2 签名比 RSA 快约 9 倍,验签反而慢一点——这跟椭圆曲线验签计算量大于签名有关。而 SM3 跟 SHA-256 差距很小,SM4 比 AES 稍慢,但都在可接受范围。
2.7 改造中的常见误区
- “SM2 密钥可以直接替换 RSA 密钥” —— 错。密钥格式不同,解析方式不同,存储长度也不同。
- “SM3 摘要是 SHA-256 的别名” —— 错。SM3 的输出值跟 SHA-256 完全不一样,不能互换。
- “SM4 支持跟 AES 一样多的密钥长度” —— 错。SM4 只支持 128 位密钥,不支持 192/256。
- “所有工作模式在两种算法间通用” —— 不完全是。像 GCM 模式在 SM4 中虽也有对应实现(SM4-GCM),但细节参数可能不同。