Search code examples
amazon-web-servicesamazon-kms

How can I call Amazon's AWS kms decrypt function without using a binary file?


I have code that retrieves a string that was encrypted using Amazon's aws kms encrypt function. I would like to call aws kms decrypt to get back the unencrypted value, but I would like to do this without writing the string to a binary file. All the examples I've found assume you will convert the base64 encoded encrypted value into a binary file using either linux's base64 command or Window's certutil command. I'm trying to do this on a Windows system. It seems to me you should be able to run:

aws kms encrypt --key-id <mykey> --plaintext "mysecret"

Which for me generates this result:

{
"KeyId": "arn:aws:kms:us-east-1:192491131326:key/<mykey>",
"CiphertextBlob": "AQICAHjQ7sViXQdeS4wWbFZpkOQWvCdNXqiy4Cnz0/xEBe39SQGz0vofeAo0+SyOXv172fqkAAAAZjBkBgkqhkiG9w0BBwagVzBVAgEAMFAGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMhchHh0ugGzwRTC4gAgEQgCMlkhYlCYk2SfYIkfQ6ruwA71KBcN7ih/OPzSE86OT/eBOz3Q=="
}

And that I should then be able to run:

aws kms decrypt --ciphertext-blob AQICAHjQ7sViXQdeS4wWbFZpkOQWvCdNXqiy4Cnz0/xEBe39SQGz0vofeAo0+SyOXv172fqkAAAAZjBkBgkqhkiG9w0BBwagVzBVAgEAMFAGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMhchHh0ugGzwRTC4gAgEQgCMlkhYlCYk2SfYIkfQ6ruwA71KBcN7ih/OPzSE86OT/eBOz3Q==

To get back the result. But so far I've been unable to get anything except:

An error occurred (InvalidCiphertextException) when calling the Decrypt operation:

Is there some set of parameters I can pass into the decrypt command so that it will decrypt this string?


Solution

  • I don't know if it's because of any change on the AWS CLI v2, but this worked for me.

    $ aws --version
    aws-cli/2.11.3 Python/3.11.2 Darwin/22.3.0 source/arm64 prompt/off
    

    I recommend to always use the --region flag just to be sure you're using the right KMS key from the region you want.

    Encrypt

    $ aws kms encrypt --region us-east-1 --key-id alias/my-kms-key --plaintext "$(echo 'MY_SECRET_TO_ENCRYPT' | base64)"
    {
        "CiphertextBlob": "AQICAHjmSj9FB9J0...",
        "KeyId": "arn:aws:kms:us-east-1:1234567890:key/...",
        "EncryptionAlgorithm": "SYMMETRIC_DEFAULT"
    }
    

    To have just the CiphertextBlob:

    $ aws kms encrypt --region us-east-1 --key-id alias/my-kms-key --plaintext "$(echo 'MY_SECRET_TO_ENCRYPT' | base64)" --output text --query CiphertextBlob
    AQICAHjmSj9FB9J0...
    

    Please note that if you encrypt the SAME string twice, you will most probably have a different CiphertextBlob and it's normal.

    Decrypt

    $ aws kms decrypt --region us-east-1 --ciphertext-blob 'AQICAHjmSj9FB9J0...' --key-id alias/my-kms-key
    {
        "KeyId": "arn:aws:kms:us-east-1:1234567890:key/...",
        "Plaintext": "TVlfU0VDUkVUX1RPX0VOQ1JZUFQK",
        "EncryptionAlgorithm": "SYMMETRIC_DEFAULT"
    }
    

    The Plaintext is encoded in base64, so to decode it:

    $ echo 'TVlfU0VDUkVUX1RPX0VOQ1JZUFQK' | base64 -d
    MY_SECRET_TO_ENCRYPT
    

    To have the decoded Plaintext directly:

    $ aws kms decrypt --region us-east-1 --ciphertext-blob 'AQICAHjmSj9FB9J0...' --key-id alias/my-kms-key --output text --query Plaintext | base64 -d
    MY_SECRET_TO_ENCRYPT