(java.security.InvalidKeyException)当cipher.init(Cipher.DECRYPT_MODE,key)出现一个预期错误时,未设置IV

Sou*_*rta 1 java encryption

SecretKey key = keyFactory.generateSecret(keySpec);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] ciphertext = cipher.doFinal(cleartext);

return bytes2String(ciphertext);
Run Code Online (Sandbox Code Playgroud)

我正在获取java.security.InvalidKeyException,即,当cipher.init(Cipher.DECRYPT_MODE,key).cleartext出现一个预期错误时,没有设置IV,这是基于base64解码字符串的字节数组。我在这里缺少什么?

Gre*_*ose 5

我不是专家,但是,您指定的是CBC模式,这需要初始化向量(IV),对于AES,它是16字节的参数。

private final static byte[] iv = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
private static final IvParameterSpec ivspec = new IvParameterSpec(iv);
Run Code Online (Sandbox Code Playgroud)

然后在调用init()方法时提供IV加密和解密。

cipher.init(Cipher.ENCRYPT_MODE, key, ivspec);
cipher.init(Cipher.DECRYPT_MODE, secretKey, ivspec);
Run Code Online (Sandbox Code Playgroud)

您永远不要使用上述方法,而应让Java为您生成随机IV或提供SecureRandom实现。

使用随机IV的目的是确保相同的纯文本不会被加密以两次生成相同的密文。这是IV的唯一目的。

将IV存储在加密文本的开头,在解密时,您知道起始的n位数字是IV。

不提供IV时,默认情况下将生成随机IV。资源

如果此密码(包括其基础反馈或填充方案)需要任何随机字节(例如,用于参数生成),它将使用已安装的最高优先级提供程序的SecureRandom实现作为随机源来获取它们。(如果没有安装的提供程序提供SecureRandom的实现,则将使用系统提供的随机性源。)

  • 您是正确的,我敢肯定您不是要暗示这个意思,但是您绝对不要像第一个代码示例那样重复使用相同的IV。 (2认同)