我有一个密钥,我想用这个密钥解密数据,但是给出了最后一个块未正确填充的错误。
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(new byte[cipher.getBlockSize()]));
byte[] encryptedBytes_updates = cipher.update(encryptedBytes);
String decryptedText = new String(cipher.doFinal(encryptedBytes_updates));
我尝试了一些来自论坛的建议,但没有运气。
可能有人可以提供帮助吗?
答案 0 :(得分:4)
如果您正在解码的消息少于16个字节,则其中一个问题可能是您使用了错误的IV。具体来说,这一行不正确:
cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(new byte[cipher.getBlockSize()]));
您正在从所有0的字节数组中创建IvParameterSpec
(因为您刚刚创建了它,但没有用任何数据填充它)。如果您在加密时做同样的事情,这就是加密/解密在本地为您工作的原因。
您需要做的是使用包含服务器发送给您的IV的字节数组创建IvParameterSpec
。如果服务器没有在单独的字段中向您发送IV,则可能是IV已经预先附加或附加到您收到的加密数据(这是一种相当普遍的做法)。我会尝试拉出加密数据的第一个块(16个字节)并将其用作IV。如果这不起作用,请尝试最后一块加密数据。或者更好的是,询问运行服务器的人或阅读手册以确定从何处获取IV。
此外,这看起来也不正确:
byte[] encryptedBytes_updates = cipher.update(encryptedBytes);
String decryptedText = new String(cipher.doFinal(encryptedBytes_updates));
为什么要将encryptedBytes_updates
带回密码并将其反馈给密码? update
解密数据,然后您尝试使用doFinal
再次解密数据。这样做:
String decryptedText = new String(cipher.doFinal(encryptedBytes));