关于加密:我应该在加密时使用初始化向量(IV)吗?

关于加密:我应该在加密时使用初始化向量(IV)吗?

Should I use an initialization vector (IV) along with my encryption?

是否建议我使用初始化向量来加密/解密我的数据? 它将使事情更安全吗? 这是需要逐案评估的事情之一吗?

为了将其置于实际上下文中,Win32密码功能CryptSetKeyParam允许在加密/解密之前在密钥上设置初始化向量。 其他API也允许这样做。

一般建议什么,为什么?


当同一密钥曾经用于加密多个消息时,IV是必不可少的。

原因在于,在大多数加密模式下,可以一起分析使用同一密钥加密的两条消息。例如,在简单的流密码中,对使用相同密钥加密的两个密文进行XOR运算会导致两个消息的XOR,使用传统的密码分析技术可以轻松地从中提取明文。

弱IV是使WEP易碎的部分原因。

IV基本上将一些唯一的非秘密数据混合到密钥中,以防止同一密钥被两次使用。


在大多数情况下,您应该使用IV。由于IV每次都是随机生成的,因此,如果两次加密相同的数据,则加密的消息将有所不同,并且观察者将无法说出这两个消息是否相同。


仔细查看CBC模式的图片(见下文)。您很快就会意识到,知道IV的攻击者就像知道先前密文块的攻击者一样(是的,他们已经知道很多)。

我的意思是:当您不确定数据完整性时,IV = 0的大多数"问题"都是块加密模式的一般问题。您确实必须确保完整性。

我的工作是:使用强校验和(加密哈希或HMAC)并在加密之前将其添加到纯文本中。有一个已知的密文第一个块:这是同一件事的IV,没有校验和,并且由于一百万个其他原因,您需要校验和。

最后:CBC和流密码之间的任何类比都不是非常有见地的恕我直言。

只要看一下CBC模式的图片,我想您会感到惊喜。

这是一张照片:

http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation

连结文字


如果同一密钥多次用于多个不同的秘密,则加密结果中可能会出现模式。 IV应该是伪随机的,并且每个密钥只能使用一次,从而混淆了结果。永远不要将同一IV和同一密钥重复使用两次,否则会破坏其用途。

不必费心跟踪IV,最简单的方法是在生成的加密机密之前或附加它。这样,您不必考虑太多。然后,您将始终知道前N位或后N位是IV。

解密机密时,您只需拆分IV,然后将其与密钥一起使用即可解密机密。


我发现HTTP Digest Auth(RFC 2617)的文字对理解IV /随机数的用法和需求非常有帮助。


Is it one of those things that need to be evaluated on a case by case
basis?

是的。务必仔细阅读所使用的密码及其期望输入的外观。有些密码不使用IV,但确实需要使用盐来确保安全。 IV可以具有不同的长度。密码的模式可以更改IV的用途(如果要使用的话),结果是,它需要保护哪些属性(随机,唯一,增量?)。

通常建议这样做,因为大多数人习惯于以"密码块链接"模式使用AES-256或类似的分组密码。对于许多工程用途而言,这是一个很好的,明智的默认方法,它需要您具有适当的(非重复)IV。在这种情况下,它不是可选的。


IV允许对纯文本进行加密,从而使攻击者更难解密加密的文本。您使用的IV的每一位都会使给定纯文本中加密文本的可能性加倍。

例如,让我们使用一个字符长的IV加密" hello world"。 IV被随机选择为" x"。然后被加密的文本就是" xhello world",即" asdfghjkl"。如果我们再次对其进行加密,则首先生成一个新的IV(例如,这次我们得到" b")并像往常一样进行加密(因此对" bhello world"进行加密)。这次我们得到" qwertyuio"。

重点是,攻击者不知道IV是什么,因此必须为给定的纯文本计算每个可能的IV,以找到匹配的密文。这样,IV就像一个密码盐。最常见的是,IV与链接密码(流密码或块密码)一起使用。在链接块密码中,每个明文块的结果被馈送到加密算法中,以查找下一个块的密文。这样,每个块都链接在一起。

因此,如果您使用随机IV来加密纯文本,该如何解密呢?简单。将IV(以纯文本格式)和加密文本一起传递。使用上面的拳头示例,最终的密文为" xasdfghjkl"(IV +密文)。

是的,您应该使用IV,但是一定要正确选择它。使用一个好的随机数源可以做到这一点。永远不要两次使用相同的IV。永远不要使用常数IV。

Wikipedia上有关初始化向量的文章提供了一般概述。


推荐阅读