在 Java 中为 AES 生成随机 IV

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29267435/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 07:42:28  来源:igfitidea点击:

Generating random IV for AES in Java

javacryptographyaesinitialization-vector

提问by user1576396

I'm implementing and AES encryption engine for PBE in android, and I've found two ways to implement the creation of the IV and I would like to know which one is better and more secure for getting IvParameterSpec:

我正在为 android 中的 PBE 实现 AES 加密引擎,我找到了两种方法来实现 IV 的创建,我想知道哪一种更好、更安全IvParameterSpec

Method #1:

方法#1:

SecureRandom randomSecureRandom = SecureRandom.getInstance("SHA1PRNG");
byte[] iv = new byte[cipher.getBlockSize()];
randomSecureRandom.nextBytes(iv);

IvParameterSpec ivParams = new IvParameterSpec(iv);

Method #2:

方法#2:

AlgorithmParameters params = cipher.getParameters();
byte[] iv2 = params.getParameterSpec(IvParameterSpec.class).getIV();

ivParams = new IvParameterSpec(iv2);

回答by Maarten Bodewes

I'd use method #1, because the Java API specifies the following for the Cipher.init()API that just takes the encryption/decryption mode and key:

我会使用方法 #1,因为 Java API 为Cipher.init()仅采用加密/解密模式和密钥的API 指定了以下内容:

If this cipher instance needs any algorithm parameters or random values that the specified key can not provide, the underlying implementation of this cipher is supposed to generate the required parameters (using its providerorrandom values).

如果此密码实例需要指定密钥无法提供的任何算法参数或随机值,则此密码的底层实现应该生成所需的参数(使用其提供程序随机值)。

(emphasis mine).

(强调我的)。

So it is not clearwhat different providers will do when method 2is chosen. Looking at the Android source code, it seems that at least some versions (including version 21?) will not create a random IV- the random IV creation seems commented out.

因此,尚不清楚不同的提供商在选择方法2时会做的。查看Android源代码,似乎至少某些版本(包括版本21?)不会创建随机IV- 随机IV创建似乎被注释掉了。

Method 1 is also more transparent and it is - in my opinion - easier on the eyes.

方法 1 也更透明,而且 - 在我看来 - 更容易看清。



Note that it is generally better to use new SecureRandom()and let the system figure out which RNG is best. "SHA1PRNG"is not well defined, may differ across implementations and is knownto have had implementation weaknesses, especiallyon Android.

请注意,通常最好使用new SecureRandom()并让系统确定哪个 RNG 最好。"SHA1PRNG"没有明确定义,可能因实现而异,并且已知存在实现弱点,尤其是在 Android 上。



So the end result should be something like:

所以最终结果应该是这样的:

SecureRandom randomSecureRandom = new SecureRandom();
byte[] iv = new byte[cipher.getBlockSize()];
randomSecureRandom.nextBytes(iv);
IvParameterSpec ivParams = new IvParameterSpec(iv);


Beware that GCM mode works best with a 12 byte IV instead of the 16 byte IV - the block size of AES.

请注意 GCM 模式最适合使用 12 字节 IV 而不是 16 字节 IV - AES 的块大小。