初始向量(IV)的CTR模式使用
据我所知,CTR 模式不使用初始向量。 它只需要一个计数器,用给定的密钥对其进行加密,然后将结果与明文进行异或以获得密文。
其他分组密码模式(例如 CBC)在进行加密之前,会使用初始向量对明文进行异或。
所以这是我的问题。我在 Java 中有以下代码(使用 bouncycastle 库):
Cipher cipher = Cipher.getInstance("AES/CTR/PKCS5Padding", "BC");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] result = cipher.doFinal("Some plaintext");
使用相同密钥对上述代码进行的每次不同调用都会给出不同的输出!但是在执行时:
byte[] IV = new byte[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
Cipher cipher = Cipher.getInstance("AES/CTR/PKCS5Padding", "BC");
cipher.init(Cipher.ENCRYPT_MODE, key, IV);
byte[] result = cipher.doFinal("Some plaintext");
我在上述代码的每次调用中都得到相同的结果。 但这是为什么呢?我的意思是,CTR 不需要 IV,那么为什么当我不在每次调用中给出 IV 时,我会得到不同的结果,而当我给出 IV 时,它会返回相同的结果? 如果我在使用 CTR 时始终使用上述 IV(全零),那会安全吗?
任何想法都会非常有帮助。 谢谢
from what I know, CTR mode doesn't use an Initial Vector.
It just takes a counter, encrypts it with a given key and then XOR's the result with the plaintext in order to get the ciphertext.
Other block cipher modes like CBC before doing the encryption they XOR the plaintext with an Initial Vector.
So here is my problem. I have the following code in Java(using bouncycastle library):
Cipher cipher = Cipher.getInstance("AES/CTR/PKCS5Padding", "BC");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] result = cipher.doFinal("Some plaintext");
Every different call of the above code with the same key gives different output! But when doing:
byte[] IV = new byte[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
Cipher cipher = Cipher.getInstance("AES/CTR/PKCS5Padding", "BC");
cipher.init(Cipher.ENCRYPT_MODE, key, IV);
byte[] result = cipher.doFinal("Some plaintext");
I take the same result in every call of the above code.
But why is this? I mean, CTR doesn't need an IV, so why when I don't give an IV in every call I get a different result and when I given an IV it returns the same result?
If I always use the above IV(all zeroes) when using CTR, would that be safe?
Any ideas would be very helpful.
Thank you
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
CTR 模式最重要的警告是,您永远、永远使用相同的键重复使用相同的计数器值。如果你这样做,你就有效地泄露了你的明文。
为了帮助实现这一点,在 CTR 模式的某些实际实现中,要传递给分组密码的块被分为两部分,标记为 IV 和计数器(而不是将整个事物称为计数器)。 IV 是随机生成的,计数器从 0 开始
。这样,只要您从不重复使用“IV”部分,就可以将多条消息的“计数器”部分从零开始。
但请注意,这只是一个标签约定。从数学上讲,这与将整个事物称为“计数器”相同,并以每条消息的某个整数的随机倍数启动计数器。
我不确定 Bouncy Castle 的具体实现是如何工作的 - 它也许可以让您使用
IV
值设置整个初始块、计数器等。如果您不提供 IV,它显然会为您生成一个合理的 IV,这就是为什么您会使用相同的输入获得不同的输出。底线是,这是好,并且正是您想要的 - 提供全零坏,而不是您想要的。The most important caveat with CTR mode is that you never, ever re-use the same counter value with the same key. If you do so, you have effectively given away your plaintext.
To assist with this, in some real-world implementations of CTR mode the block to be passed to the block cipher is split up into two parts, labelled as an IV and a counter (rather than calling the whole thing a counter). The IV is generated randomly, and the counter starts at 0.
This lets you start the "counter" part at zero for multiple messages, as long as you never re-use the "IV" part.
Note though that this is just a labelling convention. Mathematically, it's the same as calling the whole thing the "counter", and starting the counter at a random multiple of some integer for each message.
I am not sure how the Bouncy Castle implementation specifically is working - it is perhaps letting you set the entire initial block, counter and all, with the
IV
value. It is apparently generating a sensible IV for you if you do not supply one, which is why you are getting different output with the same input. The bottom line is that this is good, and exactly what you want - supplying all zeroes is bad, and not what you want.CTR 的工作原理是对计数器的连续值进行加密。该序列的第一个值是 IV(IV 表示“初始值”...)。所以 CTR 确实使用了 IV。
如果您使用 CTR 模式,使用相同的密钥,并且碰巧重用了您已经用于其他加密(使用相同的密钥)的计数器值,那么您会得到臭名昭著的两次密码,并且安全性已经下降流走。特别是,对所有消息使用固定的 IV 肯定会导致灾难。
避免计数器重复的“简单”方法是始终在一组中选择带有加密安全随机数生成器(认为“
java.security.SecureRandom
”)的 IV可能的IV,即所有16字节序列。该空间足够大,可以忽略在某个时刻重用计数器值的风险。完整地说,如果您确保给定密钥仅使用一次,则固定 IV 是可以接受的。当您使用相同的密钥重复使用相同的计数器值时,就会出现安全问题。然而,为每条消息分配一个新密钥至少与为每条消息分配一个新 IV 一样困难。
CTR works by encrypting successive values of a counter. The first value for that sequence is an IV (IV means "initial value"...). So CTR really uses an IV.
If you use CTR mode, with the same key, and happen to reuse a counter value that you already used for some other encryption (with the same key), then you get the infamous two-times-pad, and security has gone down the drain. In particular, using a fixed IV for all messages is a sure recipe for disaster.
An "easy" way to avoid counter repetition is to always select the IV with a cryptographically secure random number generator (think "
java.security.SecureRandom
") among the set of possible IV, i.e. all 16-byte sequences. That space is sufficiently large that your risk of reusing a counter value at some point can be neglected.Just to be complete, a fixed IV is tolerable if you make sure that you use a given key only once. Security problems arise when you reuse the same counter value with the same key. However, having a new key for each message is at least as difficult as having a new IV for each message.
CTR 模式使用本质上相当于 IV 的东西,即计数器的初始值。
CTR mode uses something that is essentially equivalent to an IV, and that is the initial value of the counter.