Байтбуфер в строку и наоборот разный результат

#bytebuffer #aws-kms

#bytebuffer #amazon-kms

Вопрос:

Я создал две вспомогательные функции (одну для ByteBuffer в строку и наоборот)

 public static Charset charset = Charset.forName("UTF-8");
public static String bb_to_str(ByteBuffer buffer, Charset charset){
        System.out.println("Printing start");
        byte[] bytes;
        if(buffer.hasArray()) {
            bytes = buffer.array();
        } else {
            bytes = new byte[buffer.remaining()];
            buffer.get(bytes);
        }
        return new String(bytes, charset);
    }
    
    public static ByteBuffer str_to_bb(String msg, Charset charset){
        return ByteBuffer.wrap(msg.getBytes(charset));
    }
  

У меня есть ключ данных, который я шифрую с помощью AWS KMS, который выдает мой байтбуфер.

 // Encrypt the data key using AWS KMS
ByteBuffer plaintext = ByteBuffer.wrap("ankit".getBytes(charset));
EncryptRequest req = new EncryptRequest().withKeyId(keyId);
req.setPlaintext(plaintext);    
ByteBuffer ciphertext = kmsClient.encrypt(req).getCiphertextBlob();

// Convert the byte buffer to String 
String cip = bb_to_str(ciphertext, charset);
  

Теперь проблема в том, что это не работает :

 DecryptRequest req1 = new DecryptRequest().withCiphertextBlob(str_to_bb(cip, charset)).withKeyId(keyId);
  

но это работает.

 DecryptRequest req1 = new DecryptRequest().withCiphertextBlob(ciphertext).withKeyId(keyId);
  

Что не так с моим кодом?

Ответ №1:

Ошибка заключается в попытке преобразовать произвольный байтовый массив в строку bb_to_str(ciphertext, charset); .

ciphertext ни в коем случае разумным образом не представляет читаемую строку и определенно не использует указанную вами кодировку (какой бы она ни была).

String предназначен для представления текста в Юникоде. Попытка использовать его для представления чего-либо еще столкнется с множеством проблем (в основном связанных с кодировками).

В некоторых языках программирования строковый тип представляет собой двоичную строку (т. Е. Не Представляет строго текст в Юникоде), но обычно это те же языки, которые вызывают массовые путаницы при кодировании.

Если по какой-то причине вы хотите представить произвольное byte[] значение как a String , вам нужно выбрать некоторую кодировку для его представления. Распространенным является Base64 или шестнадцатеричные строки. Base64 более компактен, а шестнадцатеричная строка концептуально проще, но занимает больше места для того же объема входных данных.