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