我正在编写一个简单的应用程序来使用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();
}
}
}
答案 0 :(得分:5)
当它在没有IV的情况下使用时,对于包括AES在内的某些类型的密码,它隐含地使用0 IV。请参阅密码类documentation。
null IV(或确定性IV)的缺点是它容易受到字典攻击。 IV的要求是防止同一个纯文本块每次产生相同的密文。
答案 1 :(得分:0)
就像其他用户所说的那样,这取决于JCE提供程序。如果未指定, Java SE 会为您生成随机IV。
只有 Android 1 和Javacard API使用空白的IV,它与Java Crypto规范which states不符:
如果此密码需要任何不能从给定
key
派生的算法参数,则基础密码实现应自行生成所需的参数(使用提供商特定的默认值或随机值)值)(如果正在初始化以进行加密或密钥包装),如果正在初始化以进行解密或密钥解包,则引发InvalidKeyException
。可以使用getParameters
或getIV
(如果参数是 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 广告一样。只是猜测,仅此而已。