3. 对称加密基础:流密码与分组密码

对称加密,说白了就是加密和解密用同一把钥匙。你想想看,就像你用一把锁锁上箱子,再用同一把钥匙打开它。这个概念很直观,但实现起来门道可不少。

我个人习惯把对称加密分成两大类:流密码和分组密码。这两者的区别,我当年学的时候也绕了好一阵子。

3.1 流密码 vs 分组密码

流密码,是一次加密一个比特或一个字节。它像一条流水线,数据流过来,密钥流就跟它做异或运算。RC4 是经典的流密码算法,不过现在已经被证明不够安全了。

分组密码,是把明文分成固定长度的块,比如 64 位或 128 位,然后逐块加密。DES、AES 都属于分组密码。

我在项目中遇到过一个问题:用流密码加密大文件时,如果密钥流重复了,整个加密就形同虚设。所以流密码的密钥管理特别重要。

特性 流密码 分组密码
处理单位 比特/字节 固定长度块
速度 通常较快 相对较慢
错误传播 无(单比特错误只影响该比特) 有(错误可能影响整个块)
典型算法 RC4, Salsa20 DES, AES
适用场景 实时通信、流媒体 文件加密、数据库加密
我的建议: 如果你不确定选哪种,优先考虑分组密码。它的安全性分析更成熟,而且有各种工作模式可以应对不同场景。

3.2 Feistel 网络结构

Feistel 网络是分组密码设计中的一个经典结构。它由 Horst Feistel 在 IBM 提出,DES 就是它的代表作。

Feistel 网络的核心思想很简单:把数据分成左右两半,然后通过多轮迭代来混淆和扩散。每一轮只处理一半的数据,另一半直接传递。

具体流程是这样的:

  1. 将明文分成左右两半:L₀ 和 R₀
  2. 对于第 i 轮(i = 1, 2, ..., n):
    • Lᵢ = Rᵢ₋₁
    • Rᵢ = Lᵢ₋₁ ⊕ F(Rᵢ₋₁, Kᵢ)
  3. 最后将 Lₙ 和 Rₙ 合并,得到密文

这里的 F 是轮函数,Kᵢ 是第 i 轮的密钥。⊕ 是异或运算。

为什么 Feistel 网络这么重要?因为它保证了加密和解密可以用相同的结构,只是密钥顺序反过来。这在硬件实现上非常方便。

关键点: Feistel 网络不要求 F 函数是可逆的。解密时,只要把加密过程反过来,F 函数自然就被抵消了。这个特性让设计者可以自由选择复杂的非线性函数,而不必担心解密问题。

我曾经在实现一个自定义加密协议时,就采用了 Feistel 结构。当时需要快速原型验证,Feistel 的对称性让代码量减少了一半。

3.3 DES 算法原理

DES(Data Encryption Standard)是 Feistel 网络最著名的应用。它由 IBM 在 1970 年代设计,后来被美国政府采纳为标准。

DES 的基本参数:

  • 分组长度:64 位
  • 密钥长度:56 位(实际密钥 64 位,其中 8 位用于奇偶校验)
  • 轮数:16 轮
  • 轮密钥长度:48 位

DES 的加密流程可以概括为:

  1. 初始置换(IP):对 64 位明文进行重排
  2. 16 轮 Feistel 迭代:每轮使用不同的 48 位子密钥
  3. 交换左右半块:最后一轮后交换 L₁₆ 和 R₁₆
  4. 逆初始置换(IP⁻¹):得到 64 位密文

每一轮的 F 函数包含四个步骤:

  1. 扩展置换:将 32 位的 R 扩展为 48 位
  2. 与子密钥异或:48 位的 R 与 48 位的 Kᵢ 异或
  3. S 盒替换:将 48 位分成 8 个 6 位块,每个块通过 S 盒变成 4 位,得到 32 位
  4. P 盒置换:对 32 位结果进行重排
注意: DES 的密钥长度只有 56 位,这在今天已经不够安全了。1999 年,EFF 的 Deep Crack 机器在 22 小时内就破解了一个 DES 密钥。现在 DES 已经被 AES 取代,但它的设计思想仍然值得学习。

下面这张图展示了 DES 的整体结构:

DES 算法结构图 DES 算法结构 64 位明文 初始置换 IP L₀ (32 位) R₀ (32 位) 16 轮 Feistel 迭代 每轮使用不同子密钥 密钥调度 56 位密钥 R₁₆ (32 位) L₁₆ (32 位) 逆初始置换 IP⁻¹ 64 位密文 解密过程与加密相同,只是子密钥使用顺序相反(K₁₆, K₁₅, ..., K₁)

DES 的 S 盒是算法的核心。每个 S 盒是一个 4×16 的查找表,输入 6 位,输出 4 位。S 盒的设计非常讲究,它提供了算法所需的非线性特性。

我记得刚学 DES 时,觉得 S 盒的设计很神秘。后来自己动手实现了一遍,才发现它的巧妙之处——S 盒的每一行都是一个双射,保证了输出不会重复。

3.4 DES 的弱点与 3DES

DES 最大的问题就是密钥太短。56 位的密钥空间只有 2⁵⁶ ≈ 7.2×10¹⁶ 种可能。在今天的计算能力面前,暴力破解已经不是难事。

为了解决这个问题,人们提出了 3DES(Triple DES)。它用三个不同的密钥(或两个密钥)对数据进行三次 DES 加密:

加密:C = E_{K3}(D_{K2}(E_{K1}(P)))
解密:P = D_{K1}(E_{K2}(D_{K3}(C)))

3DES 的有效密钥长度是 112 位(两个密钥)或 168 位(三个密钥),安全性大大提高。但它的速度很慢,因为要执行三次 DES。

避坑指南: 我曾经在项目中看到有人直接用 DES 加密敏感数据。我立刻建议他们换成 AES。如果你还在用 DES,赶紧升级吧。3DES 虽然安全,但效率太低,也不是长远之计。

现在,DES 和 3DES 都已经逐渐被 AES 取代。但 DES 的设计思想——Feistel 网络、S 盒、密钥调度——仍然是密码学的重要基础。理解 DES,就是理解现代分组密码的起点。