关于加密:在Java中,如何正确地将字节[]转换为String to Byth[]?

In Java, how to convert correctly byte[] to String to byte[] again?

我要将TEA加密的结果(字节[])转换为字符串,然后再次将其转换为字节[],并检索相同的字节[]。

1
2
3
4
5
6
7
//Encryption in the sending side
String stringToEncrypt ="blablabla"
byte[] encryptedDataSent = tea.encrypt(stringToEncrypt.getBytes());
String dataToSend = new BigInteger(encryptedDataSent).toString());

//Decryption side in the reception side
byte[] encryptedDataReceived = new BigInteger(dataToSend).toByteArray();

但是,当我尝试以下方法时:

1
2
3
4
5
6
System.out.println(new String(encryptedDataSent));

System.out.println(new String(encryptedDataReceived));

boolean equality = Arrays.equals(encryptedDataReceived,encryptedDataSent);
System.out.println("Are two byte arrays equal ? :" + equality);

输出是:

&h?7?"?PAtj??I??Z`H-jK?????f

&h?7?"?PAtj??I??Z`H-jK?????f

Are two byte arrays equal ? : false

所以,看起来两个字节[]在打印时是相同的,但它们与我们看到的"假"不完全相同,这是我在之后执行的解密的一个问题。

我还试图发送一个String with new String(byte[]),但当我们想把它转换回一个字节〔0〕时,它也有同样的问题。

我希望在开始和转换之后有完全相同的字节[]->string->byte[]

你是否有解决方案或理解我在转化过程中所做的错误?


不要试图从byte[]转换为String,就像它是常规编码的文本数据一样——它不是。它是一个任意字节数组。

最简单的方法是将其转换为base64或hex,这将导致ASCII文本可以可逆地解码回相同的二进制数据。例如,使用公共域base64编码器:

1
2
3
String dataToSend = Base64.encodeBytes(encryptedDataSent);
...
byte[] encryptedDataReceived = Base64.decode(receivedText);


尝试在解密中使用byte[]encode=base64.encode(bytestostore,base64.default)


不能。String不是二进制数据的容器。它是一个utf-16字符的容器。字符和字节之间的往返没有任何保证。


尝试显式指定字符集。UTF-8适用于主要情况:

1
2
3
4
5
6
7
8
9
10
11
public static void main(String[] args) {
    String in ="幸福";
    try {
        byte[] bytes = in.getBytes("utf-8");
        String out = new String(bytes,"utf-8");
        System.out.println(in +" ->" + out);
        System.out.println("equals:" + out.equals(in));
    } catch (UnsupportedEncodingException unsupportedEncodingException) {
        // do something
    }
}

请注意,当字节数组保持不变时,您将得到完全相同的结果。