2

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

我的问题:IV 应该为每个新的明文更改还是为每个新会话创建一个就足够了?

目前我使用 java 作为我的实现和密码类,我注意到它确实第一次创建了一个新的 IV,但是同样的 IV 也用于以后的明文。

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

谢谢 :)

4

2 回答 2

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 节。

于 2012-08-11T10:38:54.700 回答
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();

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

于 2012-08-11T10:56:04.983 回答