nsmithuk / local-kms

A mock version of AWS' Key Management Service, for local development and testing.
MIT License
198 stars 34 forks source link

AWS KMS Base64 encodes decrypted key #7

Closed nlelch closed 5 years ago

nlelch commented 5 years ago

https://docs.aws.amazon.com/kms/latest/developerguide/programming-encryption.html The Decrypting a Data Key Java implementation with local-kms returns a non base64 encoded message while AWS KMS returns it already base64 encoded. Is this intended?

nsmithuk commented 5 years ago

Hi @nlelch. Not intended; message encoding should be identical. It sounds like it may be a specific issue with the Java SDK as I'm struggling to replicate it in Go, PHP or raw HTTP.

From a purely HTTP perspective in Local KMS, I can create a data key:

http --json POST http://localhost:8080/ X-Amz-Target:TrentService.GenerateDataKey KeyId=205127e7-887a-4b07-ac92-6df4addbf58f KeySpec=AES_128
HTTP/1.1 200 OK
Content-Length: 314
Content-Type: application/x-amz-json-1.1
Date: Tue, 02 Jul 2019 07:36:03 GMT

{
    "CiphertextBlob": "S2Fybjphd3M6a21zOmV1LXdlc3QtMjoxMTExMjIyMjMzMzM6a2V5LzIwNTEyN2U3LTg4N2EtNGIwNy1hYzkyLTZkZjRhZGRiZjU4ZgAAAADObau944y8nAMh0lSNm8H+w5fOUIxSXHfEioTTW7t02eZ8DUk4hFoAHRzT5Q==",
    "KeyId": "arn:aws:kms:eu-west-2:111122223333:key/205127e7-887a-4b07-ac92-6df4addbf58f",
    "Plaintext": "Kw1lrHDovDj/RDKZ4gHfRQ=="
}

Which returns a CiphertextBlob and Plaintext, both base64 encoded.

If I then pass that CiphertextBlob back to Decrypt:

http --json POST http://localhost:8080/ X-Amz-Target:TrentService.Decrypt CiphertextBlob="S2Fybjphd3M6a21zOmV1LXdlc3QtMjoxMTExMjIyMjMzMzM6a2V5LzIwNTEyN2U3LTg4N2EtNGIwNy1hYzkyLTZkZjRhZGRiZjU4ZgAAAADObau944y8nAMh0lSNm8H+w5fOUIxSXHfEioTTW7t02eZ8DUk4hFoAHRzT5Q=="
HTTP/1.1 200 OK
Content-Length: 126
Content-Type: application/x-amz-json-1.1
Date: Tue, 02 Jul 2019 07:36:50 GMT

{
    "KeyId": "arn:aws:kms:eu-west-2:111122223333:key/205127e7-887a-4b07-ac92-6df4addbf58f",
    "Plaintext": "Kw1lrHDovDj/RDKZ4gHfRQ=="
}

I get the exact same Plaintext base64 value back as when I generated the Data Key.

Therefore it sounds like something else it trigging that Plaintext response to be base64 decoded at the Java level.

Are you able to supply me with any Java code snippets that I'm able to run against both KMSs that'll allow me to replicate the issue?

nlelch commented 5 years ago

I was using: ByteBuffer ciphertextBlob = Place your ciphertext here; DecryptRequest req = new DecryptRequest().withCiphertextBlob(ciphertextBlob); ByteBuffer plainText = kmsClient.decrypt(req).getPlaintext();

However, I missed a step in my test encryption that was throwing off the encoding and now it works as expected. Thank you for your help!