SM4 的分组是 128 位,密钥也是 128 位,支持的加密模式和填充方式看起来和 AES 完全一样。这让很多人以为两者可以互换——用 SM4 加密、用 AES 解密,或者干脆用 AES 顶替 SM4。实际上,这两套算法除了「分组长度相同」之外没有任何共同点,密文完全不兼容。
相同的地方
先看两者一致的部分,这些是使用层面的约定。
分组长度都是 128 位,也就是 16 字节。这意味着两者的 IV 都是 16 字节,NoPadding 模式下都要求明文长度是 16 的整数倍。
都支持 ECB、CBC、CFB、OFB、CTR 这些经典模式。这些模式是分组密码的通用外包装,与具体的分组算法无关,所以可以套用在任何分组长度为 128 位的算法上。
都支持 PKCS#7、ZeroPadding、ANSI X9.23、NoPadding 这些填充方式,规则也相同。
密文都可以用 Hex 或 Base64 表示。
所以从接口形态上看,把 AES 换成 SM4,只需要换一个算法名,其他参数都不用动。
不同的地方
差异全部在算法内部。
结构不同。AES 使用的是 SubBytes、ShiftRows、MixColumns、AddRoundKey 四步轮变换,属于 SP 网络结构。SM4 采用的是 32 轮非平衡 Feistel 结构,加解密使用同一套轮函数,只是轮密钥的使用顺序相反。
S 盒不同。S 盒是分组密码里提供非线性变换的核心部件,决定了算法的安全边界。AES 和 SM4 各有一套完全不同的 S 盒,取值没有任何关联。
密钥扩展不同。从 16 字节密钥派生出各轮使用的轮密钥,两者的算法完全不同。
这三处差异导致的结果是:同一把 16 字节密钥,在 AES 和 SM4 下产生的密文毫无关系,任何一方都无法解密另一方产生的密文。
SM4 的 Feistel 结构还有一个工程上的好处:加解密共用同一套电路,只需要把轮密钥顺序反过来,硬件实现非常紧凑。这一点对于智能卡、嵌入式设备这类资源受限的场景很有价值。
性能上的对比
在通用 CPU 上,两者的性能在同一量级,但 AES 通常更快。
原因是 AES 有专门的硬件指令(AES-NI),现代 x86 和 ARM 处理器都支持,可以在极少的时钟周期内完成一个分组的加密,吞吐量远高于纯软件实现。
SM4 的硬件加速支持相对少一些。不过由于它的结构简单、轮函数统一,硬件实现的面积小,在专用芯片上的效率很高。这也是它被广泛用于金融 IC 卡、政务专网设备的原因之一。
如果应用跑在通用服务器上,性能差异通常不是选型的决定因素——真正决定选型的是合规要求。
合规才是选型的核心
AES 和 SM4 都是公开、经过充分分析的算法,目前都没有实际被攻破的报道。所以纯粹从安全性角度看,两者都可以用。
选择的关键在于合规要求。
涉及国密改造的项目——例如国内的金融、政务、能源等领域的系统——监管要求使用国密算法。这时 SM4 是分组加密的标准选择,配合 SM2 做非对称加密和签名、SM3 做哈希,构成完整的国密算法体系。
反过来,面向国际市场的产品或需要与境外系统对接的项目,通常使用 AES,因为它是国际标准,兼容性最好。
还有一种情况是两者都要支持:系统内部用 SM4 满足合规,对外接口用 AES 满足互通。这时需要把加密实现抽象成一层接口,按场景分派。
迁移与验证
如果要从 AES 迁移到 SM4,或者反过来,需要重新约定所有参数。
密钥和 IV 都要重新生成——不能沿用旧的,因为算法的密钥扩展不同,旧密钥在新算法下没有意义。
密文长度可能变化,因为分组长度虽然相同,但填充的粒度变化会导致密文长度不同。如果密文存储在固定长度字段里,需要先核对。
最重要的验证手段是测试向量。SM4 有国标给出的官方测试向量,可以用它确认实现是否符合标准。跨实现对接时,也应该用一组固定数据双向验证,而不是假设「参数一样结果就一样」。
检查清单
- 两者分组长度都是 128 位,IV 都是 16 字节,支持的模式与填充也相同
- 轮函数结构、S 盒、密钥扩展完全不同,密文互不兼容
- SM4 采用 32 轮 Feistel 结构,加解密共用轮函数,硬件实现紧凑
- AES 有硬件指令加速,通用 CPU 上通常更快
- 两者安全性都可靠,选型的关键是合规要求而非强度
- 迁移时必须重新生成密钥与 IV,并用测试向量验证实现一致性