【问题标题】:Generating random IV for AES in Java在 Java 中为 AES 生成随机 IV
【发布时间】:2018-12-15 02:08:37
【问题描述】:

我正在为 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);

【问题讨论】:

    标签: java cryptography aes initialization-vector


    【解决方案1】:

    我会使用方法 #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 的块大小。

    【讨论】:

    • 这个答案是否需要更新Java 8
    • @kelalaka 不是;使用默认的 RNG 应该没问题。还是你的意思是别的?顺便说一句,Java 的更高版本甚至有 NIST DRBG 实现,所以有更多可供选择,我认为那些更安全。但即便如此,选择默认的应该没问题,特别是如果我们只是在谈论 IV。
    • 不,只是谈论选择的一般更新。是的,对于 IV 这应该足够了。
    猜你喜欢
    • 1970-01-01
    • 2020-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-15
    • 1970-01-01
    • 2011-11-08
    相关资源
    最近更新 更多