劣质的初始化向量如何影响CBC模式的安全性?

信息安全 加密 密码学 数据库 初始化向量
2021-09-09 16:37:46

(如果共识是这个问题属于加密,而不是这里,请随时 [告诉我] 迁移它。)

根据我所阅读的内容(特别是在密码块链接模式下查看 AES),初始化向量应该是不重复的,或者更好的是,至少在某些情况下,完全不可预测。如果我们考虑以下“弱化”IV的序列:

  1. 加密的随机数

  2. 任何旧的“随机数”

  3. 非重复、单调递增、非连续计数器(如高分辨率时钟)

  4. 一个 1×1 的计数器,大到不会重复,比如说受保护数据的预期有用性的 10 倍。

  5. 常数 IV

  6. 全零 IV

现在,随着我们削弱 IV,哪些攻击成为可能,以及在削弱的哪个阶段?我对“静态”存储数据特别感兴趣,目前无需身份验证。


在两个出色的答案之后,我想对可能的攻击稍微提炼一下这个问题。以下是我的一些谜题,以及一个补充问题:

  • 加密数据是信用卡号。

  • 比方说,我有客户记录,每个客户的卡都与该客户的记录相关联。

  • 我的主要最终目标是不泄露信用卡号码。

现在,我的补充问题是:据我所知,攻击者可以使用常量 IV 和密钥做的所有事情就是说“啊哈,客户 A 和客户 B 使用同一张信用卡”;到底能造成多大的伤害?

3个回答

CBC有两个不同的“危险”。请记住,CBC 的工作方式如下:加密一个块,首先将它与前一个加密块进行异或。IV 只是第一个要加密的块的“前一个加密块”。这个想法是分组密码是一种确定性排列:使用相同的密钥和相同的输入块,你会得到相同的输出。与前一个加密块的 XOR 意味着“随机化”。所以危险是:

  1. 块碰撞。
  2. 选择明文攻击。

块碰撞是指由于运气不好或缺乏随机性,一个块与前一个块的 XOR 导致一个事先已经获得的值。

例如,如果您使用一个固定的 IV(是否全零,这无关紧要),那么以相同字节序列开头的两条消息将产生两个以相同字节序列开头的加密流。这允许外人(“攻击者”)看到这两个文件在某种程度上是相同的,这可以通过块粒度来确定。这被认为是一件坏事;加密应该防止此类泄漏。

如果使用计数器作为 IV,您可能仍然会遇到这种冲突,因为计数器具有结构,而“正常”数据具有结构。作为一种极端情况,假设加密消息也以计数器开头(例如,它是协议的一部分,其中消息具有以序列号开头的标头):IV 的计数器和该计数器可以相互取消使用 XOR,将您带回到固定 IV 的情况。这不好。当加密系统提供机密性而不需要对明文格式提出一些复杂要求时,我们真的更喜欢它。作为“计数器”的高分辨率时钟也可能引发同样的问题。

选择明文攻击是指攻击者可以选择要加密的部分数据。使用 CBC,如果攻击者可以预测IV,那么他可以调整他的明文数据以匹配它。

这是BEAST攻击的基础。在 BEAST 攻击中,攻击者试图“透视”SSL。在 SSL 3.0 和 TLS 1.0 中,每条记录都使用 CBC 加密,每条记录的 IV 是前一条记录的最后一个加密块:攻击者观察线路在流中输入一些数据的位置可以推送足够的字节触发记录的发射,观察它,从而推断出将用于下一条记录的 IV,其内容将从攻击者推送的下一个字节开始。

在您展示的所有 IV 生成方法中,只有第一个(使用加密强 PRNG生成的 IV )可以保护您免受选择明文攻击。这是添加到TLS 1.1的内容。


在特定情况下,例如数据库中的信用卡,一些可能的攻击可能适用,也可能不适用。但是,不要试图“偷工减料”太多。如果您将用户数据放入数据库,则可能会应用选择明文攻击:可以查看您的数据库(例如,使用某些 SQL 注入技术)的攻击者也可能充当“基本用户”,向您提供虚假的信用卡号码,只是为了查看数据库中显示的内容。

特别是,在这种情况下,如果您使用确定性加密(这正是您使用固定 IV 得到的,无论是否全零),那么攻击者可以简单地暴力破解信用卡号码:一个数字是 16 位,但其中一个是校验和,前四位或六位来自银行,剩下的不一定是“随机的”,所以这类攻击是有效的。

底线是,如果您使用 CBC,那么您必须正确使用 CBC ,即使用强随机 IV。如果您更喜欢单调计数器(或时钟),请不要使用 CBC;相反,使用已知对单调计数器非常满意的模式,例如GCM当本书使用密码算法时,实现安全性已经够难的了,所以这里的任何“创意”都应该被回避。

当然,使用给定密钥加密的内容并不比密钥本身更机密。当攻击者对您的数据库具有读取权限时,他可能拥有对数据库以外的更多内容的读取权限——特别是对加密密钥本身的读取权限。这取决于您存储密钥的位置,以及攻击者的访问范围(SQL 注入、被盗的备份磁带、前端系统完全劫持……)。

使用 IV 的主要原因是防止相同的纯文本两次生成相同的加密文本。使用 CBC,您可以分块加密您的文本。假设您有以下文本,并且每一行都是一个块:

AAAAAA
BBBBBB
CCCCCC
DDDDDD

AAAAAA
CCCCCC
EEEEEE
FFFFFF

如果不使用 IV,则AAAAAA两个文本的加密块将是相同的。这意味着如果有人注意到加密文件开头的加密块是相同的,他就会知道另一个文件的开头是什么。

IV 背后的理念是您永远不会使用它两次。它必须是唯一的,因为如果它不是唯一的并且您有机会重复使用它,您可能会遇到前面提到的情况,由于与已知纯文本的加密版本相似,您可以恢复部分纯文本文本。

让我们一一来看看:

加密的随机数

你很安全,假设碰撞在统计上是不可能的。唯一性是我们所追求的。

任何旧的“随机数

随机性本身并不是很关键。这是碰撞的可能性。如果您的 RNG 存在短期问题或统计上更有可能出现的结果(即分布不均匀),那么您可能会损坏抗碰撞性,从而削弱 CBC。

非重复、单调递增、非连续计数器(如高分辨率时钟)

假设它是 100% 不重复的,并且您没有处于多台机器正在通信的情况(请记住时钟可能是同步的),那么您相对安全。同样,问题在于 IV 重用,因此在此模型中拥有两台具有相同时钟的机器可能会导致统计上似是而非的冲突。

一个 1×1 的计数器,大到不会重复,比如说受保护数据的预期有用性的 10 倍。

绝对没问题,假设您的计数器因素考虑了任何给定键的全局唯一性要求。

常数 IV

如果 IV 是已知的(应该假设是),这会完全破坏 CBC。出于所有意图和目的,人们可以简单地忽略 IV。

全零 IV

这再次打破了 CBC,但这只是因为它是恒定的。如果每个密钥只对一条消息使用一次,那么它仍然是安全的。IV的内容并不是特别重要。每个键都必须是唯一的。