(java.security.InvalidKeyException)当cipher.init(cipher.DECRYPT_模式,密钥)出现一个预期错误时,未设置IV

(java.security.InvalidKeyException)当cipher.init(cipher.DECRYPT_模式,密钥)出现一个预期错误时,未设置IV,java,encryption,Java,Encryption,当cipher.init(cipher.DECRYPT_模式,key)出现一个预期错误时,我得到了java.security.InvalidKeyException,即没有设置IV。明文是一个字符串base64解码的字节数组结果。我在这里缺少什么?我不是这方面的专家,但您正在指定哪个需要初始化向量(IV),对于AES,它是一个16字节的参数 SecretKey key = keyFactory.generateSecret(keySpec); Cipher cipher = Cipher.get

当cipher.init(cipher.DECRYPT_模式,key)出现一个预期错误时,我得到了java.security.InvalidKeyException,即没有设置IV。明文是一个字符串base64解码的字节数组结果。我在这里缺少什么?

我不是这方面的专家,但您正在指定哪个需要初始化向量(IV),对于AES,它是一个16字节的参数

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);
然后在调用
init()
方法时,在加密和解密时提供IV

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);
您不应该使用上述方法,让Java为您生成random IV或提供SecureRandom实现

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

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

当不提供IV时,默认情况下会生成随机IV

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

使用

private final static byte[]iv={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};

私有静态最终IvParameterSpec ivspec=新IvParameterSpec(iv);
导致我出现“焊盘块损坏错误”。我通过修改
init()
步骤解决了以下问题:

cipher.init(cipher.ENCRYPT_模式,skeySpec,新的IvParameterSpec(新字节[16]);

如果不使用
静态final
参数。

您无法得到比这更具体的错误消息。。。您使用的是CBC模式,因此需要一个IV。您是正确的,我相信您并非有意暗示这一点,但您永远不应该像在第一个代码示例中那样重用相同的IV。
cipher.init(Cipher.ENCRYPT_MODE, key, ivspec);
cipher.init(Cipher.DECRYPT_MODE, secretKey, ivspec);