java – 将字节数组转换为字符串并返回到字节数组的问题

这个主题有很多问题,同样的解决方案,但这对我来说无效。我有一个简单的加密测试。加密/解密本身工作(只要我用字节数组本身来处理这个测试,而不是像字符串)。问题是不要将其作为字节数组处理,而是以字符串方式处理,但是当我将字节数组编码为字符串并返回时,生成的字节数组与原始字节数组不同,因此解密不再起作用。我在相应的字符串方法中尝试了以下参数:UTF-8,UTF8,UTF-16,UTF8。他们都没有工作。结果字节数组与原始数组不同。任何想法为什么这样呢?

加密:

public class NewEncrypter
{
    private String algorithm = "DESede";
    private Key key = null;
    private Cipher cipher = null;

    public NewEncrypter() throws NoSuchAlgorithmException, NoSuchPaddingException
    {
         key = KeyGenerator.getInstance(algorithm).generateKey();
         cipher = Cipher.getInstance(algorithm);
    }

    public byte[] encrypt(String input) throws Exception
    {
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] inputBytes = input.getBytes("UTF-16");

        return cipher.doFinal(inputBytes);
    }

    public String decrypt(byte[] encryptionBytes) throws Exception
    {
        cipher.init(Cipher.DECRYPT_MODE, key);
        byte[] recoveredBytes = cipher.doFinal(encryptionBytes);
        String recovered = new String(recoveredBytes, "UTF-16");

        return recovered;
    }
}

这是我尝试的测试:

public class NewEncrypterTest
{
    @Test
    public void canEncryptAndDecrypt() throws Exception
    {
        String toEncrypt = "FOOBAR";

        NewEncrypter encrypter = new NewEncrypter();

        byte[] encryptedByteArray = encrypter.encrypt(toEncrypt);
        System.out.println("encryptedByteArray:" + encryptedByteArray);

        String decoded = new String(encryptedByteArray, "UTF-16");
        System.out.println("decoded:" + decoded);

        byte[] encoded = decoded.getBytes("UTF-16");
        System.out.println("encoded:" + encoded);

        String decryptedText = encrypter.decrypt(encoded); //Exception here
        System.out.println("decryptedText:" + decryptedText);

        assertEquals(toEncrypt, decryptedText);
    }
}
最佳答案
将加密数据存储在字符串中并不是个好主意,因为它们是用于人类可读的文本,而不是任意的二进制数据。对于二进制数据,最好使用byte []。

但是,如果您必须这样做,您应该使用一个在字节和字符之间具有1对1映射的编码,即每个字节序列可以映射到唯一的字符序列并返回。一种这样的编码是ISO-8859-1,即:

    String decoded = new String(encryptedByteArray, "ISO-8859-1");
    System.out.println("decoded:" + decoded);

    byte[] encoded = decoded.getBytes("ISO-8859-1"); 
    System.out.println("encoded:" + java.util.Arrays.toString(encoded));

    String decryptedText = encrypter.decrypt(encoded);

不丢失数据的其他常见编码是十六进制和base64,但很遗憾,您需要一个帮助程序库。标准API没有为它们定义类。

使用UTF-16,程序将失败的原因有两个:

> String.getBytes(“UTF-16”)向输出添加一个字节顺序标记字符,以标识字节的顺序。您应该使用UTF-16LE或UTF-16BE来实现此目的。
>并非所有字节序列都可以映射到UTF-16中的字符。首先,以UTF-16编码的文本必须具有偶数个字节。其次,UTF-16具有超越UFFFF的unicode字符编码的机制。这意味着例如有4个字节的序列映射到只有一个unicode字符。为了可能,4的前2个字节不对UTF-16中的任何字符进行编码。

转载注明原文:java – 将字节数组转换为字符串并返回到字节数组的问题 - 代码日志