在Java中为AES生成随机IV

时间:2015-03-25 22:05:06

标签: java cryptography aes initialization-vector

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

方法#1:

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

IvParameterSpec ivParams = new IvParameterSpec(iv);

方法#2:

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

ivParams = new IvParameterSpec(iv2);

1 个答案:

答案 0 :(得分:16)

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

  

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

(强调我的)。

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

方法1也更透明,在我看来 - 眼睛更容易。


请注意,通常最好使用new SecureRandom()并让系统确定哪个RNG最佳。 "SHA1PRNG"定义不明确,可能因实现不同而已知在Android上存在实施漏洞,尤其是


所以最终结果应该是:

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

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