Blowfish 是由 Bruce Schneier 在 1993 年设计的一种对称分组加密算法。它的设计目标是替代 DES 等较早的加密算法,提供更快速且安全的加密方案。与 DES 相似,Blowfish 算法也使用 Feistel 结构。
算法原理
Blowfish 使用 64 bit 的加密块大小,密钥长度支持 32-448 bit 长度。加密过程中需要用到 P 数组(18 个 32 bit 元素)和 S 盒(4 个 S 盒,每个有 256 个元素,元素大小为 32 bit)加密流程非常简单,可以用一图表示:
F 轮函数
Blowfish 的 F 函数也设计的非常简单,可以用一图表示:
简单来说就是将 32 bit 的输入分为 4 部分,每个部分经过 S 盒替换,再将替换后的结果经过模加和异或运算获取最终的 32 bit 输出。
P 数组和 S 盒扩展
这个算法最复杂的部分其实是这里,虽然 P 数组和 S 盒有默认值,他们的初始值是 $\pi$ 的小数部分转换为 16 进制。但是目前看下来,好像和我们输入的密钥没有什么关系。那么输入的密钥是怎样参与到加密中的呢,就是在 P 数组和 S 盒的扩展过程中。1
- 首先将 P 数组和输入的密钥进行异或操作作为新的 P 数组,密钥长度最高为 448 bit,这是肯定不够用的,故会循环使用,即 $k_{14}$ 用完后开始用 $k_1$ 进行异或操作。
- 使用上述更新后的 P 数组和 S 盒加密全为 0 的 64 bit 数据,将加密后的 64 bit 结果作为新的 $P[0],P[1]$。然后使用更新后的 P 数组和 S 盒继续加密上一次的输出结果作为新的 $P[2],P[3]$。直到更新完 P 数组所有的元素。
- 使用上一步最终的加密结果作为输入,进行一次加密,将加密结果作为新的 S 盒中的元素。后续操作与步骤 2 相同,直到更新完 S 盒中的所有元素。
加密
此时我们拥有了更新后的 P 数组和 S 盒,可以正式对明文进行加密了,加密流程在图一中已经很清晰。需要注意的是在 Blowfish 加密算法中,P 数组 S 盒在加密每个 64-bit 明文块之前并不会重新更新。P 数组和 S 盒的更新仅发生在密钥调度阶段,也就是在使用用户提供的密钥初始化 Blowfish 算法的过程中进行一次性的更新。