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,同时提供机密性与完整性,是现代推荐选择。

下面这张图给出对称加密的整体数据流与两条技术路线的分叉关系,便于对照理解“密钥—明文—密文”的走向以及分组/流密码的差异。

明文 P 原始数据 / 消息 密钥 K 128/192/256 位 加密算法 E 公开算法 C = E(K, P) 分组密码 Block Cipher 固定分组:AES 128 位 / SM4 128 位 模式:CBC / CTR / GCM 需 IV / nonce,GCM 提供 AEAD 流密码 Stream Cipher 密钥流:ChaCha20 / RC4(已弃用) C = P ⊕ KS,逐字节/逐位 nonce 重复即密钥流复用,致命 密文 C 不可读 / 可传输 解密 D(K, C) 还原明文 P 攻击面 密钥 / 模式 / nonce

三、流密码:逐位异或的密钥流

流密码(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 唯一、版本绑定、完整性校验
关键判断:如果系统只做“加密”而没有完整性保护,攻击者可以篡改密文并观察解密行为,CBC 填充预言攻击就是典型例子。正确做法是使用 AEAD 模式(如 AES-GCM),或严格采用 Encrypt-then-MAC 结构。

五、一个可执行的教学示例

下面用 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 唯一、标签校验”作为上线前的三项硬性检查。

记忆锚点:分组密码像“把数据切成固定大小的砖块再逐块加工”,流密码像“用一条与数据等长的随机带子逐位覆盖”。前者必须选对模式,后者必须保证 nonce 不重复;两者共同的前提都是密钥保密与算法公开。