这是一个非常简单的问题,涉及初始化向量(IV),当使用对称加密(例如AES)与CBC一起使用时。
我的问题:对于每个新明文,IV是否应该更改,或者是否足以为每个新会话创建一个?
目前我正在使用java作为我的实现和Cipher Class,我注意到它确实第一次创建了一个新的IV,但同样的IV也用于后来的明文。
也许有一些关于这个主题的阅读资源?
谢谢:)
答案 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();
请注意,上面的代码不提供完整性保护。