8

据我所知,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(全零),那会安全吗?

任何想法都会非常有帮助。谢谢

4

3 回答 3

7

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.

于 2011-02-10T00:58:14.060 回答
3

CTR 通过加密计数器的连续值来工作。该序列的第一个值IV(IV 表示“初始值”......)。所以 CTR 确实使用了 IV。

如果您使用 CTR 模式,使用相同的密钥,并且碰巧重用了您已经用于其他加密的计数器值(使用相同的密钥),那么您会得到臭名昭著的两次填充,并且安全性已经下降流走。特别是,对所有消息使用固定的 IV 肯定会导致灾难。

避免计数器重复的“简单”方法是始终在可能的 IV 集合(即所有 16 字节序列)中选择具有密码安全随机数生成器(想想“ ”)的 IV。java.security.SecureRandom该空间足够大,可以忽略在某些时候重用计数器值的风险。

为了完整起见,如果您确保只使用给定密钥一次,则可以容忍固定的 IV。当您使用相同的密钥重用相同的计数器值时,就会出现安全问题。但是,为每条消息拥有一个新密钥至少与为每条消息拥有一个新 IV 一样困难。

于 2011-02-10T16:03:52.047 回答
0

CTR 模式使用本质上等同于 IV 的东西,即计数器的初始值。

于 2011-02-10T00:14:16.593 回答