(java.security.InvalidKeyException)在cipher.init上有一个预期错误时没有设置IV(Cipher.DECRYPT_MODE,key)

时间:2016-09-10 05:03:51

标签: 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);

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

2 个答案:

答案 0 :(得分:4)

我不是这方面的专家,但是,您指定的CBC mode需要初始化向量(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);

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

cipher.init(Cipher.ENCRYPT_MODE, key, ivspec);
cipher.init(Cipher.DECRYPT_MODE, secretKey, ivspec);

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

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

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

当不提供IV时,它将默认生成随机IV。 Source

  

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

答案 1 :(得分:0)

使用

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);

为我导致了“ 填充块损坏错误 ”。我通过修改init()步骤来解决以下问题:

cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(new byte[16]));

不使用static final参数。