我正在为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);
答案 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的块大小。