加密算法选型:AES、SM4 为国密算法,密钥长度与性能权衡

说到 TDE 加密,第一步就是选算法。市面上那么多算法,为什么我重点拎出 AES 和 SM4?

说白了就两个原因:一是合规,二是通用。AES 是国际标准,性能经过几十年验证;SM4 是国家密码管理局推行的国密算法,国内政企项目绕不开。我在好几个金融客户的 TDE 改造中都碰过选型决策——选错了后面改起来,那叫一个痛苦。

算法核心对比:AES vs SM4

先把最关键的参数摆出来。下面这张表是我整理项目时常用的,你可以直接贴在 wiki 上。

对比维度 AES (Rijndael) SM4 (原 SMS4)
标准来源 FIPS PUB 197(美国) GM/T 0002-2012(中国)
分组与密钥长度 128 位分组;密钥 128/192/256 位 128 位分组;密钥 128 位
轮数 10/12/14 轮(对应密钥长度) 32 轮
结构类型 Substitution-Permutation Network (SPN) Feistel 网络
软件实现性能 极高(AES-NI 指令集加速) 中等(无原生指令加速)
硬件实现面积 中等 较小(适合嵌入式)
密钥扩展复杂度 简单(反向时需耗时 key schedule) 简单(解密时需消耗额外轮密钥)

密钥长度怎么选?

AES 提供三种密钥长度:128、192、256。你会不会觉得越长越安全?嗯,理论上是的,但实际要考虑侧面。

  • AES-128:安全强度足够,几乎所有场景够用。我见过有些老系统还在用 128 位,没出过事。
  • AES-192:很少用,不上不下,做中间过渡可以。
  • AES-256:安全边际最高,但性能开销约是 128 位的 1.4~1.6 倍。我曾在一个券商核心交易系统里测试过,256 位加密后 TPS 下降了 12%,128 位只降了 5%,最后业务方选了 128。

SM4 只有 128 位密钥,没得选。是不是很遗憾?其实国密专家认为 128 位足够对抗未来十年的计算力了,你想想看,对称密钥 128 位的暴力破解需要 2^128 次尝试,就算量子计算机出来目前也只能把强度砍到 2^64——依然不可行。

结论:如果你不是为防“存储密码100年后仍能被解”的极端场景,选 AES-128 或 SM4 就行。AES-256 只在需要符合特定合规(如某些政府机密级)时才硬上。

性能权衡:那点性能差距重要吗?

重要,但不致命。我在之前做某银行网银系统的 TDE 时,对比过几组数据:

算法模式 加解密吞吐 (MiB/s) CPU 使用率增量 备注
AES-128-CBC 820 +3.2% 启用 AES-NI
AES-256-CBC 540 +5.8% 启用 AES-NI
SM4-CBC 210 +8.5% 纯软件实现
SM4-CTR (并行优化) 290 +6.9% 纯软件 + 线程并行

你看,SM4 只有 AES-128 的四分之一不到。但你要注意,表里 SM4 是纯软件,没有硬件加速。而 AES 有 CPU 里的 AES-NI 指令集,这个差距是结构性的。我建议:如果项目跑在国产 CPU(如鲲鹏、飞腾)上,它们大多也已经支持 SM4 硬件加速了,实测能到 500~700 MiB/s,基本可以忽略性能担忧。

避坑:我曾经在一台老旧的 Intel Xeon E5 上部署 SM4,没做任何优化,结果加密一个小型 MySQL 库,IO 就飙到 95%,业务直接超时。后来改用硬件安全模块(HSM)卸载加密才解决。所以,如果服务器不支持 SM4 硬件加速,你又必须用 SM4,建议考虑 HSM 或软硬件协同方案。

画张决策图帮你理清思路

下面这张图是我做 TDE 方案设计时常用的选型流程,从业务需求到最终算法选择,一目了然。

TDE 加密算法选型决策流程 业务合规需求评估 是否要求支持国密算法? 是 否 选用 SM4 检查是否支持硬件加速 (CPU HSM 或国密加密卡) 选用 AES 评估性能预算 AES-128 还是 AES-256? 确定算法 + 密钥长度 进入 TDE 接口配置 注:SM4 仅有 128 位密钥;AES 推荐默认 AES-128,仅在合规要求或极端安全需求下升级到 AES-256。

实战建议:到底怎么选?

我个人的经验是,把决策点拆成三块:

  1. 看政策红线——如果项目涉及密评或等保三级以上,国密是刚需,直接上 SM4 没什么好纠结的。记得提前调研 HSM 或 CPU 加速支持。
  2. 看性能底线——拿你的业务最大吞吐量去压测。我习惯用 openssl speed 跑一轮,把 AES-128、AES-256、SM4 三个数字记下来,看 CPU 占用是否超过告警线。如果 SM4 纯软实现下 CPU 增量超过 10%,就要考虑硬件卸载了。
  3. 看运维成本——用 AES 可以复用操作系统和中间件自带的加密库,SM4 可能需要额外装驱动或补丁包。我在一个项目里踩过坑:SM4 的 OpenSSL 引擎版本不兼容导致 k8s 启动失败,排查了整整一个下午。

小技巧:如果是新项目,我建议一开始就把加密算法做成可配置的。比如在配置文件中写 cipher_algorithm=AES-128-CBC,这样以后换国密只用改一行配置和重启服务,不用动代码。这也是“无侵入式”的一部分。

关于密钥扩展与解密的隐藏成本

你可能觉得选好算法和密钥长度就完事了。其实还有一个容易被忽略的点:解密时的密钥扩展开销。

AES 的 key schedule 在加密方向很简单,但解密时需要用逆轮密钥,需要把整个扩展链算出来。SM4 的 Feistel 结构则是对称的,加密和解密流程几乎一样,只是轮密钥反向使用。所以如果你用 SM4,解密性能和加密基本一致;AES 如果每次解密都重新跑 key schedule,加密方向和解密方向会差 10%~20%。

我在一个高并发读取场景中(比如分布式数据库页面解密),就特意把 AES 的轮密钥缓存到内存里,避免每次解密都重复计算。这个优化让整体解密延迟降低了 15 微秒,虽然不大,但在百万 QPS 下就是质变。

一句话总结

选 AES-128 还是 SM4?先看合规再看性能。AES 有硬件加速优势,SM4 有政策护城河。只要做好性能压测和硬件权衡,两者都能在生产环境稳定运行。最后别忘了检查密钥扩展的隐藏成本——十几年前的教训,我帮你提前避了。