2. Feistel 网络基础:对称结构、轮函数、加解密对称性
聊 FF1 和 FF3 之前,咱们得先把地基打牢。这个地基就是 Feistel 网络。说白了,它是一种构造分组密码的经典框架。很多现代算法——比如 DES、Blowfish,还有咱们要讲的 FF1 和 FF3——都是在这个骨架上长出来的肉。
我个人习惯把 Feistel 网络看作一个「分而治之」的瑞士军刀。你想想看,把一个长长的数据块直接做加密,数学上很麻烦。但要是把它劈成两半,每轮只折腾其中一半,另一半原地不动?那事情就简单多了。
2.1 对称结构:左半和右半
Feistel 网络的结构其实非常直观。咱们来看它的核心设计:
- 分块处理:输入的数据块会被切成两等份——左半(L)和右半(R)。
- 迭代轮数:这两块数据会经过多次相同的操作,每一轮叫一个「轮(Round)」。
- 角色互换:每一轮结束后,左半和右半会交换位置,然后进入下一轮。
我在项目中调试过一些自己造的 Feistel 原型,有个坑让我印象很深:千万别把左右两半的大小弄成不对称的。要是左半比右半长一截,那后面几轮的平衡性会彻底乱掉。FF1 和 FF3 都要求左右两半长度差不超过 1,就是这个道理。
关键点:Feistel 的对称性来源于左右两半的结构完全相同。加密和解密共用一套轮函数,只是密钥使用的顺序相反。
2.2 轮函数:整个网络的引擎
轮函数 F 是 Feistel 网络里最核心的部分。它接收右半数据 Ri 和本轮密钥 Ki 作为输入,输出一个固定长度的伪随机串。
然后这个输出会和左半数据 Li 做异或(XOR),结果成为下一轮的右半 Ri+1。
公式很简单:
Li+1 = Ri
Ri+1 = Li ⊕ F(Ri, Ki)
为什么要强调这个公式?因为它揭示了一个重要的特性:轮函数 F 可以是任意函数,甚至不要求可逆。加密时怎么算,解密时也怎么算,完全不用修改 F 本身。嗯,这里要注意:很多人会误以为 F 需要可逆,其实不需要。这也是 Feistel 架构精巧的地方。
我记得有一次优化一个旧版 FF3 的实现,瓶颈就出在轮函数 F 对数字和字母混合域的处理上。当时改了改 F 内部的查表策略,性能提升了 30% 还多。轮函数的设计,直接决定了加密速度和安全性。
小技巧:在实际实现中,轮函数 F 通常包含:密钥扩展、非线性替换(比如 S 盒)、线性置换(比如 P 盒)三个步骤。FF1 和 FF3 的 F 内部还嵌入了 AES 或 SM4 这样的标准分组加密算法,用来生成伪随机掩码。
2.3 加解密对称性:一模一样的结构
Feistel 网络最让我觉得「优雅」的地方,就是它的加解密对称性。加密和解密走的是同一套流程,唯一的区别在于子密钥的使用顺序。
咱们来看:
- 加密流程:使用密钥 K0, K1, ..., Kn-1 依次应用每一轮。
- 解密流程:使用密钥 Kn-1, Kn-2, ..., K0 也就是逆序应用即可。
你可能会问:为什么可以这样?咱们推导一下。给定一轮加密:
Li+1 = Ri
Ri+1 = Li ⊕ F(Ri, Ki)
解密时,已知 (Li+1, Ri+1),想恢复 (Li, Ri):
Ri = Li+1
Li = Ri+1 ⊕ F(Li+1, Ki)
你看,F 函数被直接复用了,连实现代码都不用动。我曾经在一个嵌入式项目中为了省 ROM 空间,加密和解密模块直接用了同一个函数,只传不同的密钥顺序参数。硬件资源紧张的时候,这种对称性能省下不少事。
避坑指南:虽然 Feistel 解密只改了密钥顺序,但有些库(比如某些旧版 PyCryptodome)在实现 DES 时,解密和加密的轮函数内部有微妙的边界检查差异。我曾经被这种“对称但不完全对称”的 bug 坑过一整天。所以不管你用哪个库,做加解密对称性验证时,一定得写单元测试,用多组随机数据跑一遍。
2.4 两种常见的 Feistel 变体
| 特性 | 传统 Feistel (FH-X) | 非平衡 Feistel (FH-P) |
|---|---|---|
| 左右分块大小 | 严格相等 | 可以不相等 |
| 典型应用 | DES, FF1 | FF3 |
| 轮函数设计难度 | 相对较低 | 需要更复杂的域处理 |
| 安全性证明 | 经典成熟 | 轮数要求更高 |
FF1 用的是传统的平衡 Feistel,左右两半大小一致,数学证明很成熟。FF3 用的是非平衡 Feistel(也叫 FH-P),左右两半在第二轮之后会出现长度差异。我个人觉得,非平衡 Feistel 虽然更灵活,但也更容易踩坑——比如左右两半的域处理函数必须不同,否则会出现不安全的相关性。
2.5 一图看懂 Feistel 网络
下面这张图展示了 Feistel 网络一轮加密的完整流程。你注意看左右两半的流动方向,还有轮函数 F 的输入输出位置。
2.6 实际应用中的感悟
我个人觉得,Feistel 网络最大的贡献不是数学上的突破,而是工程上的「可复制性」。你只要把轮函数 F 设计好,整个加密算法的骨架几乎不用变。FF1 和 FF3 虽然是针对格式保持加密设计的,但它们的核心还是这个老骨架。
最后,我有个温馨提醒:无论是研究 FF1 还是 FF3,先把 Feistel 网络的左移右移、异或、密钥顺序这三个基本动作刻在脑子里。后面几十章的内容,都是在这个框架上做文章。