当cipher.update(...)成功时,cipher.doFinal(...)失败

时间:2016-02-29 00:06:22

标签: java encryption aes block-cipher

我正在尝试使用以下代码解密字节数组。为简洁起见,我省略了异常处理和其他做法:

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
byte[] key = getKey(); \\Assume it is implemented.
byte[] iv = getIv(); \\Assume it is implemented;
SecretKeySpec sc = new SecretKeySpec(key, "AES");
cipher.init(Cipher.DECRYPT_MODE, sc, new IvParameterSpec(iv));
byte[] encrypted = getBytesFromFile(); \*Assume it is implemented. Simply reads bytes from a binary file into a byte array and returns them as are.*\
byte[] clear = new byte[cipher.getOutputSize(encrypted.length)];
int processed = cipher.doFinal(encrypted, 0, encrypted.length, clear, 0);

注意:Java本身不支持PKCS7Padding,但我确实通过添加securtiy BouncyCastleProvider来实现它。为了论证,PKCS5Padding也存在同样的问题。

import org.bouncycastle.jce.provider.BouncyCastleProvider;

问题:

doFinal throws抛出 BadPaddingException:pad block corrupt 。但是,如果我用 update 替换 doFinal ,那就是:

int processed = cipher.update(encrypted, 0, encrypted.length, clear, 0); 

完美无缺。结果如预期。

有些人可以帮助我了解区别是什么以及如何让doFinal工作?如果需要更多信息,请告诉我。

1 个答案:

答案 0 :(得分:1)

您没有显示加密,最好的选择是填充确实不正确。要在没有PKCS7Padding的情况下检查此解密,您将能够看到填充并确定它是否正确。

错误显示在doFinal中,因为这是检查填充的位置,如果正确则删除。

执行此操作并将解密数据转储(十六进制,因为填充将是0x01 - 0x10范围内的字节。