我在字符串和字节数组之间来回转换时遇到问题。
基本上我已经制作了一个小程序来使用AES加密和解密消息。
加密消息后会发生这种情况:
byte[] result = cipher.doFinal(message.getBytes());
String stringResult = new String(result);
将加密的邮件转换为字符串。 现在我的解密器使用以下命令将字符串更改回一个字节:
byte[] result = stringResult.getBytes();
但是当它解密消息时(取决于消息)它可能无法解密。似乎有填充问题,我得到的错误是:
线程“main”中的异常javax.crypto.BadPaddingException:给定最终块未正确填充
为什么会出现这种情况?
确实发生这种情况的一个例子是当加密密钥是“1231231231231231”并且加密的消息是“已读”时。
答案 0 :(得分:3)
您正在使用平台默认编码 - 一次将消息转换为字节,然后一次将加密的任意二进制输出转换回字符串。这两个步骤都存在问题。
首先,在将字符串转换为字节时,最好使用已知覆盖整个Unicode的固定编码。 UTF-8通常是一个不错的选择。
然后就是将任意二进制数据表示为文本。这不是编码中表示的文本数据 - 它是二进制数据。解释它好像它是文本数据几乎肯定会丢失信息。您需要更强大的功能,能够绕过任意二进制数据。 Base64通常是要走的路。
据我所知,有一个public domain base64 encoder可以很好地运作。所以你的加密代码变成了:
byte[] result = cipher.doFinal(message.getBytes("UTF-8"));
String stringResult = Base64.encodeBytes(result);
解密代码将是:
byte[] encrypted = Base64.decode(encryptedBase64);
byte[] decrypted = /* do the decryption here */
String message = new String(decrypted, "UTF-8");
答案 1 :(得分:0)
您的加密字节是二进制数据,不太可能在转换为字符串后返回。如果需要将其存储在字符串中,则Base64对其进行编码。