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 整体对比框架

先看一张图,把三组的脉络理清。

国密与主流国际算法对比总览 国密 vs 国际算法 对比总览 SM2 椭圆曲线公钥密码 密钥长度:256位 签名/加密/密钥交换 RSA 大整数分解公钥密码 密钥长度:2048/3072/4096位 签名/加密/密钥交换 SM3 国密哈希算法 输出256位,消息长度<=2^64 结构:Merkle-Damgård SHA-256 国际通用哈希算法 输出256位,消息长度<=2^64 结构:Merkle-Damgård SM4 国密分组密码 分组128位,密钥128位 结构:Feistel网络(32轮) AES 国际通用分组密码 分组128位,密钥128/192/256位 结构:SPN(10/12/14轮) 核心差异点 • 密钥结构不同 • 算法轮数/结构不同 • 性能特征不同 为什么要替换? • 密码合规要求 • 抗量子计算能力 • 国产自主可控 • 国家等保/密评要求 我的建议 先理解差异,再动手改造 避免‘无脑替换’

2.3 SM2 vs RSA —— 椭圆曲线 vs 大整数分解

SM2 跟 RSA 都是公钥密码,但底层数学完全不同。RSA 靠大整数分解的困难性,SM2 靠椭圆曲线离散对数问题。

我个人习惯先说结论:SM2 在同等安全强度下,密钥长度短得多,运算速度快得多。你想想看,RSA 2048 位的密钥在嵌入式设备上要做一次私钥操作,动辄几十毫秒,而 SM2 只要几百微秒——差了一个数量级。

关键指标对比
对比项SM2RSA
底层数学难题椭圆曲线离散对数大整数分解
密钥长度(位)2562048 / 3072 / 4096
签名性能(倍)约 10x 快基准
加密/解密性能加密慢,解密快加密快,解密慢
密文膨胀小(密钥点 + hash)大(模数长度)
标准文档GM/T 0003-2012PKCS#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,但仔细一对比,发现轮函数、常量、消息扩展全部不一样。

我给你们看一组核心差异:

特性SM3SHA-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-2012FIPS PUB 180-4
避坑指南: 我曾经在一个签名验签项目中,误以为 SM3 输出结构跟 SHA-256 完全一致,直接把 SM3 的摘要当 SHA-256 摘要传给验证接口。结果验签怎么都不过。后来排查才发现——SM3 的初始向量(IV)和 SHA-256 不同,导致相同输入下摘要值完全不同。一定不要犯这个错!

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 接入的人来说,关心的是 调用的接口长什么样。

我的个人经验: 在做国密 SD 库封装时,我习惯把 SM4 的 ECB、CBC、CTR 模式跟 AES 的对应模式放在同一个抽象层下。这样上层业务改造时,只需要改算法标识,不需要改模式逻辑。你看这样写:
// 伪代码示意
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 改造中的常见误区

  1. “SM2 密钥可以直接替换 RSA 密钥” —— 错。密钥格式不同,解析方式不同,存储长度也不同。
  2. “SM3 摘要是 SHA-256 的别名” —— 错。SM3 的输出值跟 SHA-256 完全不一样,不能互换。
  3. “SM4 支持跟 AES 一样多的密钥长度” —— 错。SM4 只支持 128 位密钥,不支持 192/256。
  4. “所有工作模式在两种算法间通用” —— 不完全是。像 GCM 模式在 SM4 中虽也有对应实现(SM4-GCM),但细节参数可能不同。
总结一句话: 国密不是国际算法的“换皮”,它在数学原理、密钥结构、算法细节上都做了独立设计。做改造时,一定不要想当然地画等号。我建议你对照本章的对比表格,逐项检查你的业务场景。