CTR模式使用初始向量(IV)

时间:2011-02-09 22:45:14

标签: java cryptography initialization-vector block-cipher

据我所知,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时它会返回相同的结果? 如果我在使用点击率时总是使用上面的IV(全零),那会安全吗?

任何想法都会非常有用。 谢谢

3 个答案:

答案 0 :(得分:6)

使用点击率模式的最重要警告是,您永远不会使用相同的密钥重复使用相同的计数器值。如果你这样做,你就已经有效地放弃了你的明文。

为了协助这一点,在CTR模式的一些实际实现中,要传递给分组密码的块被分成两部分,标记为IV和计数器(而不是将整个事件称为计数器) 。 IV是随机生成的,计数器从0开始。

这样,只要您不再重复使用“IV”部分,就可以为多条消息启动“计数器”部分为零。

请注意,这只是一个标签惯例。在数学上,它与调用整个事物“计数器”相同,并以每个消息的某个整数的随机倍数启动计数器。

我不确定Bouncy Castle实现是如何工作的 - 它可能让你设置整个初始块,计数器和所有,IV值。如果你不提供一个显然为你产生合理的IV,这就是为什么你用相同的输入得到不同的输出。最重要的是,这是,正是你想要的 - 提供所有零是,而不是你想要的。

答案 1 :(得分:3)

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

如果您使用CTR模式,使用相同的密钥,并且碰巧重复使用已经用于其他加密(使用相同密钥)的计数器值,那么您将获得臭名昭着的两倍垫,并且安全性已经走了下来。特别是,对所有消息使用固定的IV是确定的灾难方法。

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

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

答案 2 :(得分:0)

CTR模式使用的东西基本上等于IV,这是计数器的初始值。