3. 对称加密核心原理
对称加密的“对称”二字,指的是加密与解密使用同一把密钥。理解这一点之后,真正决定安全强度的并不是“有没有加密”,而是加密算法如何把密钥与明文混合成密文,以及密钥是否被正确生成、分发、使用和销毁。本节围绕四个基本对象——明文、密钥、密文、算法——展开,并区分分组密码与流密码两条技术路线,最后落到安全目标与攻击面上。
一、四个基本对象与安全目标
在对称加密模型中,发送方把明文 P 和密钥 K 输入加密算法 E,得到密文 C = E(K, P);接收方用同一密钥执行解密 D(K, C) = P。这里有一个容易被忽视的前提:算法本身是公开的,安全性完全依赖密钥的保密性,这就是柯克霍夫原则(Kerckhoffs's Principle)。因此“算法保密”不能作为安全边界,密钥管理才是工程重点。
对称加密通常要同时满足几个安全目标:机密性(未授权者无法从密文还原明文)、完整性(密文被篡改可被发现,通常需配合 MAC 或 AEAD 模式)、抗重放(旧密文不能被重复利用,需 nonce/序列号)、以及不可预测性(密文不应泄露明文模式)。需要强调:裸加密只提供机密性,不提供完整性,这是大量真实漏洞的根源。
二、分组密码:把数据切成固定大小的块
分组密码(Block Cipher)把明文按固定长度分组,例如 AES 分组长度为 128 位(16 字节),密钥长度可为 128/192/256 位。它对每个分组执行多轮代换与置换(AES 为 SubBytes、ShiftRows、MixColumns、AddRoundKey 四步循环),使输入与输出之间呈现高度非线性关系。分组密码本身只定义“单块如何变换”,实际使用必须选择工作模式。
常见模式及其工程含义:
- ECB:相同明文块产生相同密文块,会泄露数据模式,不应使用。
- CBC:需要随机 IV,逐块链式加密,串行处理;解密可并行,但必须配合 MAC 防篡改。
- CTR:把分组密码当作伪随机流生成器,可并行、可随机访问,但 nonce 绝不能重复。
- GCM:CTR + GHASH,属于 AEAD,同时提供机密性与完整性,是现代推荐选择。
下面这张图给出对称加密的整体数据流与两条技术路线的分叉关系,便于对照理解“密钥—明文—密文”的走向以及分组/流密码的差异。
三、流密码:逐位异或的密钥流
流密码(Stream Cipher)不切分固定块,而是用密钥和 nonce 生成一条与明文等长的密钥流 KS,再逐字节或逐位异或:C = P ⊕ KS。它的优点是无需填充、延迟低、适合实时通信;缺点是密钥流一旦重复使用,安全性立即崩溃。因为若同一密钥流加密两条消息,攻击者做 C1 ⊕ C2 = P1 ⊕ P2,明文异或结果会直接暴露语言统计特征。
以 ChaCha20 为例,它使用 256 位密钥、96 位 nonce 和 32 位计数器,每 64 字节生成一个密钥流块。工程上必须保证同一密钥下 nonce 不重复;若计数器溢出,必须更换密钥。RC4 因密钥流偏差已被主流协议弃用,不应在新系统中使用。
四、基本攻击面与工程判断
对称加密的攻击面可以按“密钥—算法—模式—实现—协议”五层来梳理:
| 攻击面 | 典型攻击 | 工程对策 |
|---|---|---|
| 密钥 | 弱密钥、暴力破解、密钥泄露 | 使用 CSPRNG 生成,AES-128 起步,密钥不落盘明文 |
| 算法 | 已知弱点算法(DES、RC4) | 选用 AES-GCM、ChaCha20-Poly1305、SM4-GCM |
| 模式 | ECB 模式泄露、CBC 填充预言 | 禁用 ECB,CBC 必须 Encrypt-then-MAC |
| 实现 | 时序侧信道、缓存侧信道 | 使用常量时间比较,优先硬件 AES-NI |
| 协议 | 重放、IV 复用、降级攻击 | nonce 唯一、版本绑定、完整性校验 |
五、一个可执行的教学示例
下面用 OpenSSL 演示 AES-256-GCM 的加密与解密过程。示例参数为教学假设,实际部署应使用随机生成的密钥与 nonce,并通过安全通道分发。
# 生成 256 位随机密钥(32 字节)
openssl rand -out key.bin 32
# 生成 96 位随机 nonce(12 字节)
openssl rand -out nonce.bin 12
# 加密:AES-256-GCM,输出密文与认证标签
openssl enc -aes-256-gcm -K $(xxd -p -c 32 key.bin) \
-iv $(xxd -p -c 12 nonce.bin) \
-in plain.txt -out cipher.bin
# 解密并验证认证标签
openssl enc -d -aes-256-gcm -K $(xxd -p -c 32 key.bin) \
-iv $(xxd -p -c 12 nonce.bin) \
-in cipher.bin -out plain.out
观察要点:若密文被篡改一个字节,GCM 解密会直接失败并报错,而不是输出错误明文——这正是完整性保护的价值。若 nonce 重复使用,即使密钥正确,机密性也会被破坏。因此工程上应把“密钥唯一、nonce 唯一、标签校验”作为上线前的三项硬性检查。