对称加密算法详解:AES、DES/3DES、SM4
对称加密,说白了就是加密和解密用同一把钥匙。你加密时用的密钥是什么,解密时就必须原样拿出来。这个概念听起来简单,但实际落地时坑太多了。记得我刚工作时,为了赶进度直接用了 DES,结果被安全审计直接打回来——那时候我才明白,算法选错,整条业务线都在裸奔。
这一章我带你过三个最常见的对称加密算法:AES、DES/3DES、SM4。它们各有脾气,选对了省心,选错了半夜被叫起来修漏洞。你想想看,要是加密性能跟不上,高并发下 CPU 直接飙到 100%,那画面多美。
AES:当前的事实标准
AES(Advanced Encryption Standard)是 NIST 在 2001 年推出来的,现在已经成了对称加密的“默认选项”。它支持 128/192/256 位密钥,分组长度固定 128 位。我个人习惯,只要项目没有特殊约束,一律用 AES-256。
算法原理上,AES 把数据分成 16 字节一块,然后做多轮替换和置换。具体来说:
- 密钥长度:128 位(10 轮)、192 位(12 轮)、256 位(14 轮)
- 核心操作:SubBytes(S 盒替换)、ShiftRows(行移位)、MixColumns(列混合)、AddRoundKey(轮密钥加)
- 解码过程:反向操作,但轮密钥顺序反过来
这里有个容易被忽视的点:解密和加密的代码路径不一样,硬件实现时面积会翻倍。我在项目中遇到过用软件实现 AES 的团队,结果把加密和解密写成一个函数,靠参数切换——性能差了 30%,因为 CPU 没法做流水线优化。
AES 模式选择
模式决定了分组加密怎么处理长数据。我用一张表把常见模式列出来:
| 模式 | 特点 | 典型场景 | 我踩过的坑 |
|---|---|---|---|
| ECB | 每个分组独立加密,相同明文得到相同密文 | 几乎不要用 | 千万别用,能直接看到明文模式 |
| CBC | 前一个密文块参与当前块加密,需要 IV | 文件加密、存储 | IV 必须是随机且不可预测的 |
| CTR | 计数器递增,加密后与明文异或 | 需要随机访问的场景 | 计数器绝不能重复,否则异或就能破解 |
| GCM | CTR + 认证标签,同时保证机密性和完整性 | 网络传输、TLS | Nonce 长度通常 12 字节,别用 96 位以外的 |
⚠ 避坑指南:我曾经在 IoT 项目里为了省存储空间,直接拿设备的 MAC 地址当 IV,结果被攻击者通过已知明密文对拆解出密钥。后来换成每包随机生成 12 字节 Nonce,再也没出过事。
DES/3DES:该退场了,但还在遗产系统里活着
DES(Data Encryption Standard)是七十年代的产物,密钥只有 56 位。1999 年就被证明可以暴力破解——当时 EFF 花 25 万美元就造出了一台 24 小时内破解 DES 的机器。现在你拿 AWS p3 实例,估计几分钟就破掉。
3DES 是把 DES 做了三次:加密-解密-加密(EDE 模式)。有效密钥长度 112 位或 168 位。但它的分组还是 64 位,性能只有 AES 的 1/5 到 1/10。我建议所有新设计都别碰它。
💡 经验之谈:如果你在维护一个老系统,里面全是 3DES 代码,迁移策略是:先让两端同时支持 3DES 和 AES,用灰度流量切,等确认没问题再下线 3DES。一刀切的下场就是——有人半夜打电话给你说“数据解密失败了”。
SM4:国产密码算法,合规场景绕不开
SM4 是国家密码管理局发布的对称加密算法,分组 128 位,密钥 128 位,32 轮迭代。结构上有点类似 AES,但采用了非线性变换 τ(S 盒 + 线性变换 L)。记得 2018 年做一个政务云项目,客户硬性要求必须用 SM4,当时团队里没人写过,我临时啃了 GM/T 0002 标准,才发现国内实现普遍有个问题——把 S 盒写死了,没按标准到轮密钥中更新。
SM4 的模式和 AES 一样,支持 ECB、CBC、CTR、GCM(国标里叫 SM4-XTS 或 SM4-GCM)。但从性能上看:
- 纯软件实现:SM4 比 AES-128 慢 2~3 倍
- 硬件加速:如果 CPU 支持 AES-NI,AES 快 5 倍以上;SM4 目前只有部分国产芯片有专用指令
- 安全强度:128 位密钥,当前足够,但量子计算出现后都得升级
📌 重点:选择哪个算法,优先级应该是:
① 合规要求(如等保、密评)→ SM4
② 跨平台兼容 + 性能 → AES-256-GCM
③ 历史遗留系统 → 先评估再迁移,别硬改
对称加密核心流程对比
下面这张图帮你快速理清三个算法的关系和选型逻辑:
性能对比实测参考
我自己用 OpenSSL 1.1.1 在 x86_64 服务器上跑过 benchmark,数据说话:
| 算法 | 密钥长度 | 加密速度(MB/s) | 解密速度(MB/s) | 备注 |
|---|---|---|---|---|
| AES-128-CBC | 128 | ~1200 | ~1100 | 带 AES-NI 加速 |
| AES-256-CBC | 256 | ~950 | ~880 | 多两轮,慢 20% |
| 3DES-168-CBC | 168 | ~60 | ~55 | 暴慢,慎用 |
| SM4-CBC | 128 | ~400 | ~380 | 纯软件,无专用指令 |
| SM4-GCM | 128 | ~350 | 同加密 | 加认证会略降 |
🔧 实战建议:如果你的服务跑在 ARM 芯片(比如手机、树莓派)上,SM4 纯软件性能可能更差,因为 ARM 的 NEON 指令集对 AES 有优化,对 SM4 支持参差不齐。选型前务必在目标硬件上做一次实际压测,别只看网上的数字。
模式选择黄金法则
模式选不好,算法再强也白费。我总结了几条,你直接照着用:
- 通用情况:直接上 AES-256-GCM。既加密又认证,不用额外算 HMAC。
- 需要随机访问:CTR 模式,但必须保证 Nonce 不重复。我在分布式系统里用时间戳 + 全局计数器组合,避免跨节点冲突。
- 合规要求:SM4-GCM 或 SM4-CTR,国标 GM/T 0002-2012 有明确示例。
- 别碰 ECB:除非你只加密单个分组且长度固定(比如几字节),否则密文会泄露明文模式。
⚠ 致命陷阱:我曾经见过一个团队把文件分块用 CTR 加密,结果每个块从 Nonce=0 开始,所有块的加密密钥流完全一样。攻击者只要收集到第一个块的密文,就能通过异或恢复后面的明文。血的教训:Nonce 必须每次变化,且不能重用。
嗯,对称加密就这些。你掌握了 AES 和 SM4,再理解模式差异,90% 的加密场景都能覆盖。DES 和 3DES 就当历史知识吧,别在生产新代码里写就行。