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