AES / CBC真的需要IV参数吗?

问题描述 投票:5回答:2

我正在编写一个简单的应用程序来使用AES / CBC(模式)加密我的消息。由于我的理解CBC模式需要IV参数,但我不知道为什么我的代码工作没有使用IV参数。有谁能解释为什么?谢谢。

打印的加密消息:T9KdWxVZ5xStaisXn6llfg ==无例外。

public class TestAES {

public static void main(String[] args) {

    try {
        byte[] salt = new byte[8];
        new SecureRandom().nextBytes(salt);

        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        KeySpec keySpec = new PBEKeySpec("myPassword".toCharArray(), salt, 100, 128);

        SecretKey tmp = keyFactory.generateSecret(keySpec);
        SecretKeySpec key = new SecretKeySpec(tmp.getEncoded(), "AES");

        Cipher enCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        enCipher.init(Cipher.ENCRYPT_MODE, key);

        // enCipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));

        byte[] cipherBytes = enCipher.doFinal("myMessage".getBytes());
        String cipherMsg = BaseEncoding.base64().encode(cipherBytes);

        System.out.println("Encrypted message: " + cipherMsg);

    } catch (Exception ex) {
        ex.printStackTrace();
    }

}
}
java aes password-encryption cbc-mode
2个回答
5
投票

当它在没有IV的情况下使用时,对于某些类型的密码,包括AES,它隐含地使用0 IV。请参阅密码类documentation

null IV(或确定性IV)的缺点是它易受字典攻击。 IV的要求是防止同一个纯文本块每次产生相同的密文。


0
投票

像其他用户所说,这取决于JCE提供商。如果您指定none,Java SE会为您生成随机IV。

只有Android1和Javacard API使用空白IV,这不符合Java Crypto规范,which states

如果此密码需要任何无法从给定的key派生的算法参数,则底层密码实现应该自行生成所需的参数(使用特定于提供程序的默认值或随机值),如果它正在初始化以进行加密或密钥包装,并且如果正在初始化解密或密钥解包,则引发InvalidKeyException。可以使用getParametersgetIV检索生成的参数(如果参数是IV)。

如果你没有指定IV,在Java SE中你会得到一个随机的IV,并且需要使用cipher.getIV()检索它并存储它,因为解密需要它。

但更好的是,自己生成一个随机IV并通过IvParameterSpec提供它。

    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

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

    cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "AES"), ivParams);

    byte[] ciphertext = cipher.doFinal(input.getBytes());

1这可能是因为Android是Java风格的,就像Eminem-esque广告一样。只是猜测,就是这样。

© www.soinside.com 2019 - 2024. All rights reserved.