Расшифровка ключа данных в Java AWS SDK приводит к бреду

Так что я читаю, читаю и смотрю на примеры и... с треском проваливаюсь. Вот моя ситуация:

У меня есть CMK в KMS, и я сгенерировал ключ данных, например так:

$ aws kms generate-data-key --key-id 64a62e3e-7e38-4f86-8ef2-3d00929e6260 --key-spec AES_256
{
   "Plaintext": "+SjeaxtD5TIhOcY16+A2NA493MbxnYozbzZx4i3/BfA=", 
   "KeyId": "arn:aws:kms:us-west-2:040512153658:key/64a62e3e-7e38-4f86-8ef2-3d00929e6260", 
   "CiphertextBlob": "AQIDAHgrvfqfgn9D0tTUJOISzFCz7ejMPZ6/HGX0kGAlzKYZ7wEiyHdpuGaOjpq4UQazPAgeAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMU5JtbI6lxLOv/p4KAgEQgDsX97Pk+ywqLU2VymLRgDSz0exOyzRgLMgd7WEf3sLUh4GnbYllIrxNSdK/DSZrYUhBo78KYugnkTj89g=="
}

Затем я проверяю это, расшифровывая из CLI:

$ aws kms decrypt --ciphertext-blob fileb://<(echo 'AQIDAHgrvfqfgn9D0tTUJOISzFCz7ejMPZ6/HGX0kGAlzKYZ7wEiyHdpuGaOjpq4UQazPAgeAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMU5JtbI6lxLOv/p4KAgEQgDsX97Pk+ywqLU2VymLRgDSz0exOyzRgLMgd7WEf3sLUh4GnbYllIrxNSdK/DSZrYUhBo78KYugnkTj89g==' | base64 -d) --query Plaintext
"+SjeaxtD5TIhOcY16+A2NA493MbxnYozbzZx4i3/BfA="

И вот! Я получаю значение Plaintext, все красиво и чисто. Затем я пытаюсь отшлифовать этот же самый зашифрованный BLOB-объект через SDK, используя Java со следующим кодом:

    .
    .
    .
    final String encryptedCipherText = "AQIDAHgrvfqfgn9D0tTUJOISzFCz7ejMPZ6/HGX0kGAlzKYZ7wEiyHdpuGaOjpq4UQazPAgeAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMU5JtbI6lxLOv/p4KAgEQgDsX97Pk+ywqLU2VymLRgDSz0exOyzRgLMgd7WEf3sLUh4GnbYllIrxNSdK/DSZrYUhBo78KYugnkTj89g==";
    final String expectedPlainText = "+SjeaxtD5TIhOcY16+A2NA493MbxnYozbzZx4i3/BfA=";

    AWSKMS kmsClient;
    String returnValue;

    kmsClient = AWSKMSClientBuilder
            .standard()
            .withRegion("us-west-2")
            .build();

    ByteBuffer cipherTextBlob = ByteBuffer.wrap(Base64.getDecoder().decode(encryptedCipherText));
    DecryptRequest decryptRequest = new DecryptRequest().withCiphertextBlob(cipherTextBlob);
    ByteBuffer key = kmsClient.decrypt(decryptRequest).getPlaintext();
    final byte[] bytes = new byte[key.remaining()];
    key.duplicate().get(bytes);
    String result = new String(bytes);
    if (expectedPlainText.equals(result)) {
        LOG.info("decrypted plaintext matches expected");
    } else {
        LOG.error("decrypted plaintext unexpected value: " + result);
    }
    .
    .
    .

И выгруженная запись в журнале была:

23:08:33.210 [main] ERROR com.eyefinity.magicmissile.aws.AwsClientConfig - decrypted plaintext unexpected value: �(�k�2!9�5��64=���3o6q�-��

Я пытался кодировать результат с каждой доступной мне кодировкой, и ни одна из кодировок не выдала мой оригинальный ключ открытого текста. Насколько я могу судить из всех примеров, которые я видел, мой код правильный. Так что я делаю не так или чего мне здесь не хватает? Все, что я хочу - это получить переменную Java String, которая содержит "+SjeaxtD5TIhOcY16+A2NA493MbxnYozbzZx4i3/BfA=".

2 ответа

Решение

Я наткнулся на собственное решение: я был ТАК ЗАКРЫТ! Все, что требуется в приведенном выше коде для извлечения того же значения открытого текста, которое возвращается из KMS, и строки ASCII, которую я получил в командной строке aws-cli при генерации ключа данных, - это взять массив байтов, а Base64 его кодировать. Поэтому, ссылаясь на мой пример кода выше, полностью вверху, замените строку, которая гласит...

String result = new String(bytes);

с чем-то вроде этого:

String result = Base64.getEncoder().encodeToString(bytes);

У меня аналогичная проблема.

Я уже сгенерировал DataKey из AWS KMS (получая открытый ключ и зашифрованный ключ). Теперь предположим, что мне нужно использовать ключ открытого текста для шифрования файла, сохранить зашифрованный ключ с окончательным зашифрованным файлом и удалить ключ открытого текста.

      //AWS KMS requesting data key
GenerateDataKeyRequest dataKeyRequest = new GenerateDataKeyRequest()
dataKeyRequest.setKeyId(keyId)
dataKeyRequest.setKeySpec("AES_256")

GenerateDataKeyResult dataKeyResult = awskmsClient.generateDataKey(dataKeyRequest)
ByteBuffer plaintextKey = dataKeyResult.getPlaintext()
ByteBuffer encryptedKey = dataKeyResult.getCiphertextBlob()

Как зашифровать файл в Java 7 с помощью этого ключа открытого текста? Я имею в виду, что есть несколько способов сделать это, но какой из них наиболее эффективен и безопасен с использованием шифра AES_256, который я запрашиваю у AWS KMS для получения ключей?

Я не могу использовать AWS Encryption для этого (даже было бы проще), потому что o версия Java 7.

Другие вопросы по тегам