OFB 和 CTR 将分组密码转换为流密码。这意味着在使用它们时必须小心,例如RC4;重复使用相同的流来加密两个不同的消息是一种致命的罪过。OFB 在这方面更“微妙”。由于 OFB 包括重复加密相同的值,因此在实践中,它是对置换循环的探索:IV 选择一个点,而 OFB 遍历包含该点的循环。对于块大小为n位的块密码,一个周期的平均大小应该在2 n/2左右,如果你加密的更多,那么你开始重复流的前一段,这很糟糕。当n = 64时,这可能是一个大问题(例如,您使用 3DES)。此外,这是一个平均值:由于(运气不好),您可以达到较小的周期;此外,如果您使用相同的密钥但不同的 IV 加密两条消息,您可能(如果不走运,再次出现)与以前相比(仅在不同的点)达到相同的周期。
OFB 的缺点是很难测试这些情况(如果实现包含必要的代码,它可以测试这些不希望的情况是否发生,但这不能提前完成,只有在部分加密已经完成的情况下)完毕)。对于 CTR,事情就简单多了:CTR 是连续计数器值的加密;当一个计数器值被重用时,麻烦就开始了。但是计数器的行为很容易预测(毕竟它是一个计数器),因此更容易确保使用相同密钥加密的连续消息使用不同范围的计数器值。
此外,当使用 CTR 加密时,输出在大约2 n/2个块后开始与纯随机区分开来,但这很少是致命的。这是一个令人担忧的问题,足以保证使用具有大块的分组密码(例如,使用 128 位块而不是 3DES 及其 64 位块的 AES),但与 OFB 相比,这是一种更优雅的安全降级。
综上所述,不要使用OFB;改用点击率。这不会使 CTR 易于安全使用,只是更容易。为避免搞砸它,您应该尝试使用一种经过身份验证的漂亮加密模式,该模式可以正确执行并包括完整性检查,这是一个必要但经常被忽视的组件。EAX和GCM是我首选的 AE 模式(EAX 在 L1 缓存有限的小型架构上会更快,GCM 在现代 x86 上会更快,尤其是那些使用专门为此定义的AES 操作码的架构)。
据我所知,CFB 不会像 OFB 那样受到周期长度问题的影响,但是用 CFB 加密一长串零相当于 OFB;因此,与 CFB 相比,更喜欢 CTR似乎更安全。
几乎所有的分组密码操作模式在达到2 n/2屏障时都会遇到问题,因此无论如何使用 128 位分组是明智的。
注意: CFB 和 OFB 有一个可选的“反馈长度”。通常,我们使用全块反馈,因为这可以确保最大性能(每次调用块密码产生n位密文)。还定义了具有较小反馈的模式,例如 CFB-8,它一次只加密一个字节(因此当使用 64 位块密码时,它比全块 CFB 慢 8 倍)。现有库不太支持此类模式;此外,小的反馈回路会使 OFB 问题变得更糟。因此,我不建议使用 CFB 或 OFB 会小于全块反馈。
正如@Rook 所指出的:CBC 模式与 ECB 类似,但与 CFB、OFB 和 CTR 不同,它只处理完整的块,因此需要填充。填充可能意味着填充预言攻击,这是不好的(可以说,填充预言攻击只有在不使用 MAC 或应用不当的情况下才有可能;正确的方法是先加密然后 MAC)。出于这个原因,无填充模式比 CBC 更可取。
这导致我们在 CTR 上明显战胜了其他模式,CFB 位居第二,然后是 CBC 和 OFB,然后是 ECB(当然,这有点主观)。但是,实际上,使用 EAX 或 GCM。