AES 加密 - 密钥与 IV

Posted

技术标签:

【中文标题】AES 加密 - 密钥与 IV【英文标题】:AES Encryption - Key versus IV 【发布时间】:2012-02-21 09:58:52 【问题描述】:

我正在开发的应用程序允许用户加密文件。文件可以是任何格式(电子表格、文档、演示文稿等)。

对于指定的输入文件,我创建了两个输出文件——一个加密数据文件和一个密钥文件。您需要这两个文件来获取原始数据。密钥文件必须仅适用于相应的数据文件。它不适用于来自同一用户或任何其他用户的任何其他文件。

AES 算法需要两个不同的加密参数,一个密钥和一个初始化向量 (IV)。

我看到创建密钥文件的三个选择:

    在应用程序中嵌入硬编码 IV 并将密钥保存在密钥文件中。 在应用程序中嵌入硬编码密钥并将 IV 保存在密钥文件中。 将密钥和 IV 保存在密钥文件中。

请注意,不同客户使用的是同一个应用程序。

看起来所有三个选择都将实现相同的最终目标。不过,我希望得到您对正确方法的反馈。

【问题讨论】:

【参考方案1】:

当您使用 IV 时,最重要的是 IV 应该尽可能独特,因此在实践中您应该使用随机 IV。这意味着不能将其嵌入到您的应用程序中。我会将 IV 保存在 data 文件中,因为它不会损害安全性只要 IV 是随机的/唯一的

【讨论】:

最终的想法是确保黑客无法破解加密文件。 IV 的大小似乎小于密钥的大小。如果密钥是固定的并且 IV 是变化的,正如您所建议的,黑客将有更少的组合来尝试破坏打开文件。有什么我想念的吗? IV 不是为了“确保黑客无法破解加密文件”。这是为了确保,如果你对同一个文件进行两次加密,它会产生不同的加密输出。 bdolan 那条小消息终于让我的硬币掉了下来。我一直在努力理解 IV 与消息长度相比的重要性,但我认为这不是真的,但它很重要与消息内容相比......谢谢!【参考方案2】:

关于 IV 的重要一点是您绝不能将相同的 IV 用于两条消息。其他一切都是次要的——如果你能确保唯一性,随机性就不那么重要了(但仍然是一件非常好的事情!)。 IV 不需要(实际上,在 CBC 模式下不能)是秘密的。

因此,您不应将 IV 与密钥一起保存 - 这意味着您对每条消息都使用相同的 IV,这违背了拥有 IV 的意义。通常,您只需将 IV 以明文形式添加到 加密 文件中。

如果您打算像这样推出自己的密码模式,请阅读相关标准。 NIST 在这里有一份关于密码模式的好文档:http://dx.doi.org/10.6028/NIST.SP.800-38A IV 生成记录在附录 C 中。密码学是一门微妙的艺术。不要试图在正常密码模式上创建变体; 99% 的时间您会创建看起来更安全,但实际上不太安全的东西。

【讨论】:

@Peter,这不是 IV 的用途。特别是,如果 IV 未知,但密钥已知,则在 CBC 模式下,黑客将无法恢复明文的第一个块。但是,他们将能够恢复其余的明文。 IV 的唯一目的是扰乱文件,以便重复加密不会产生相同的输出(因此,攻击者无法通过看到密文相同来判断两个文件具有相同的内容)。 编辑:我删除了我以前的 cmets。我同意,阅读 I cwe.mitre.org/data/definitions/329.html 表明您应该使用随机 IV 而不是重复使用它。基于密码、盐等会违反这一点。 如果您只使用静态 IV 来加密随机数据(会话密钥或其他派生密钥),那么使用静态 IV 是有意义的。否则,您应该使用随机 IV,如果您为每条加密消息提供额外的 字节空间,那么您不妨一直使用一个。 @owlstead,如果您使用固定的 IV,确保消息的第一个纯文本块始终是唯一的至关重要。消息作为一个整体是独一无二的是不够的。此外,如果您的消息是单个明文块的大小(例如,派生密钥)并且是唯一的,您可以简单地使用 ECB 模式。 IV 有不同的用途,具体取决于所使用的操作模式。在 CTR 中,它必须是唯一的,以防止出现many-time pad。在 CBC 中,它是 unpredictable 并且不是唯一的。消息计数器是唯一的,对于 CTR 模式来说是可以的,但对于 CBC 模式来说就不好了。【参考方案3】:

正如您从其他答案中看到的那样,每个加密文件都有一个唯一的 IV 至关重要,但这是为什么呢?

首先 - 让我们回顾一下为什么每个加密文件的唯一 IV 很重要。 (Wikipedia on IV)。 IV 为您的加密过程的开始增加了随机性。当使用链式块加密模式(其中一个加密数据块包含先前的加密数据块)时,我们会遇到关于第一个块的问题,这就是 IV 的来源。

如果您没有 IV,并且仅使用您的密钥使用链式块加密,则以相同文本开头的两个文件将生成相同的第一个块。如果输入文件在中途发生更改,则两个加密文件将开始看起来不同,从该点开始一直到加密文件的末尾。如果有人在一开始就注意到了相似之处,并且知道其中一个文件的开头是什么,他就可以推断出另一个文件的开头是什么。知道明文文件的开头是什么以及对应的密文是什么,可以让该人确定密钥,然后解密整个文件。

现在添加 IV - 如果每个文件使用随机 IV,它们的第一个块将不同。上述情况已被阻止。

现在,如果每个文件的 IV 都相同怎么办?好吧,我们又遇到了问题场景。每个文件的第一个块将加密为相同的结果。实际上,这与根本不使用 IV 没有什么不同。

现在让我们来看看您提出的选项:

选项 1. 在应用程序中嵌入硬编码 IV 并将密钥保存在密钥文件中。

选项 2. 在应用程序中嵌入硬编码密钥并将 IV 保存在密钥文件中。

这些选项几乎相同。如果两个以相同文本开头的文件生成以相同密文开头的加密文件,那你就完蛋了。这两种选择都会发生。 (假设有一个主密钥用于加密所有文件)。

选项 3. 将密钥和 IV 都保存在密钥文件中。

如果您对每个密钥文件使用随机 IV,那就很好。没有两个密钥文件是相同的,每个加密文件都必须有它的密钥文件。不同的密钥文件将不起作用。

PS:一旦您选择了选项 3 和随机 IV - 开始研究如何确定解密是否成功。从一个文件中获取一个密钥文件,并尝试使用它来解密另一个加密文件。您可能会发现解密继续进行并产生垃圾结果。如果发生这种情况,请开始研究authenticated encryption。

【讨论】:

解密需要IV。 但是,(至少在 CBC 模式下)错误的 IV 只会破坏第一个块,您仍然可以解密剩余的文件内容。 我在这里的几个地方看到了与上述类似的 cmets(“错误的 IV 只会破坏第一个块,您仍然可以解密剩余的文件内容”)。这不是真的。由于加密的第一个块是第二个块的 IV(依此类推),未知的 IV 意味着没有块可以被解密。***上的 CBC 图很清楚地说明了这一点:link @Rich - 我知道我的评论晚了 4 年,但是......我尝试使用损坏的 IV 使用 .NET AES 库进行解密。只有第一个块被破坏。这是因为,加密的块是 CBC 中下一个块的 IV...并且当解密第一个块以外的其他块时,您始终拥有加密的前一个块。 @Les - 也许晚了 4 年,但你是绝对正确的。我的上述评论对于 CBC 来说是完全错误的。不知道我在想什么。谢谢。【参考方案4】:

IV 用于通过随机性提高安全性,但这并不意味着它被所有算法使用,即

关键是静脉输液应该多长时间?通常它与块大小或密码大小相同。例如,AES 将有 16 个字节用于 IV。此外,IV类型也可以选择,即eseqiv、seqiv、chainiv ...

【讨论】:

以上是关于AES 加密 - 密钥与 IV的主要内容,如果未能解决你的问题,请参考以下文章

如何安全地为 AES CBC 加密生成 IV?

对称加密及AES加密算法

使用 aes_256_cbc 密码加密时的默认 IV 是啥?

有没有办法在没有 iv 的情况下在 openssl 中运行 aes-128-cbc 加密?

如何使用Bouncy Castle解密AES / CCM加密密文?

AES加密使用Php,javascript,反之亦然