初始化向量(IV) - 更新频率

时间:2012-08-11 06:36:16

标签: encryption cryptography encryption-symmetric

这是一个非常简单的问题,涉及初始化向量(IV),当使用对称加密(例如AES)与CBC一起使用时。

我的问题:对于每个新明文,IV是否应该更改,或者是否足以为每个新会话创建一个?

目前我正在使用java作为我的实现和Cipher Class,我注意到它确实第一次创建了一个新的IV,但同样的IV也用于后来的明文。

也许有一些关于这个主题的阅读资源?

谢谢:)

2 个答案:

答案 0 :(得分:4)

在CBC中,为了最大限度地提高安全性,IV必须是不可预测的。

Should the IV change for each new plaintext or
does it suffice to create one for each new session?

我并不完全清楚你给" 明文"和" 会话"。

如果你的意思是每个会话都有一个新的,新的密钥,并且交换的数据被分割成碎片然后加密,那么CBC通常会应用于整个链条,这意味着密文块片P n-1 的片段可以用作片P n 的IV。因此,整个会话只需要一个IV。

Perhaps there is some reading resources about this topic?

当然,NIST SP 800-38A,第6.2节。

答案 1 :(得分:3)

注意:此答案仅与CBC模式加密中的IV有关。

您需要使用相同的密钥为每个单独的加密“会话”创建新的IV。对于要加密安全的IV,应该从攻击者的随机数中不可知。默认情况下,Java使用零IV,这意味着您不应该重用密钥来创建其他密文。

所以不,你不应该在没有设置新IV的情况下重复使用会话。基本上,对于任何协议唯一安全的是下面的源代码。有一些方法可以使用协议中的其他信息创建安全的IV,但我不会参与其中。

Cipher aes = Cipher.getInstance("AES/CBC/PKCS5Padding");

// repeat this for each cipher text
byte[] ivBytes = new byte[aes.getBlockSize()];
SecureRandom rnd = new SecureRandom();
rnd.nextBytes(ivBytes);
aes.init(Cipher.ENCRYPT_MODE, sk, new IvParameterSpec(ivBytes));

// now prepend the ivBytes to the output, e.g. by writing it to a stream first
// remove and use as IV at the receiving side

[编辑]:忘记了这个简写符号:

aes.init(Cipher.ENCRYPT_MODE, sk, new SecureRandom());
byte[] ivBytes = aes.getIV();

请注意,上面的代码不提供完整性保护。