让我们来看看你的Java代码:
String c = new String(Test.encrypt((new String("thevalue")).getBytes(),
(new String("mykey")).getBytes()));
...
System.out.println("Base64 encoded String:" +
new sun.misc.BASE64Encoder().encode(c.getBytes()));
你在这里做的是:
- 使用系统的默认编码将纯文本字符串转换为字节
- 使用系统的默认编码将密钥转换为字节
- 加密字节
-
使用系统的默认编码将加密字节转换回字符串
-
使用系统的默认编码将加密字符串转换回字节
- 使用 Base64 对这些加密字节进行编码。
问题出在步骤 4 中。它假定任意字节数组表示系统默认编码中的字符串,并且将此字符串编码回来会给出相同的字节[]。这对于某些编码(例如系列)有效,但对其他编码无效。在Java中,当某些字节(或字节序列)在给定的编码中不可表示时,它将被其他一些字符替换,稍后用于重新转换的字符将映射到字节63(ASCII)。实际上,文档甚至说:ISO-8859
?
当给定字节在默认字符集中无效时,此构造函数的行为未指定。
在你的情况下,根本没有理由这样做 - 只需使用您的方法直接输出的字节将它们转换为Base64。encrypt
byte[] encrypted = Test.encrypt("thevalue".getBytes(),
"mykey".getBytes());
System.out.println("Base64 encoded String:"+ new sun.misc.BASE64Encoder().encode(encrypted));
(另请注意,我在这里删除了多余的构造函数调用,尽管这与您的问题无关。new String("...")
要记住的一点是:永远不要将任意字节[](不是来自编码字符串)转换为字符串。加密算法(以及除解密以外的大多数其他加密算法)的输出肯定属于不应转换为字符串的数据类别。
永远不要使用系统的默认编码,如果你想要便携式程序。