12
votes

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?

2
In your example, the returned CiphertextBlob and the passed --ciphertext-blob are similar... but not identical... values.Michael - sqlbot
I'm very impressed that you noticed that, but it was just me making a mistake of copying from multiple sources when forming the question, and not the source of the problem. I just repeated the test and verified that the cipher text blob was the same in both commands, and yet I get the same error.Bert Cushman
I also got same error when I tried same thing as you did. It turns out that you can not combine certutil with kms decrypt commands. That's why in the official document, we need to save binary file for windows. docs.aws.amazon.com/cli/latest/reference/kms/decrypt.htmlMing M Zheng

2 Answers

17
votes

Not sure if you've already found this, but this seems to work:

aws kms decrypt --ciphertext-blob fileb://<(echo "{YOUR CIPHERTEXTBLOB HERE}" | base64 -d) --output text --query Plaintext --region {REGION} | base64 -d

This is for a Mac. On Windows I think you need base64 -d.

Hope this helps.

7
votes

I do a stuff with aws kms so I wanted a way to work with streams rather than files. I have define 2 functions in my shell that could also be put into scripts. (I left the semicolons in because I have these condensed to oneliners in my .bash_profile but I like to break things up when I'm "teaching".)

export KMS_KEY=b31ef212-168e-4f7c-ab2a-fe8a623ee465

kmse(){
  local key=${1:-$KMS_KEY};
  aws kms encrypt \
    --key-id $key \
    --plaintext "$(cat /dev/stdin)" \
    --query CiphertextBlob \
    --output text;
}

kmsd(){
  aws kms decrypt \
    --ciphertext-blob fileb://<( \
      cat /dev/stdin | \
      sed 's/.*kmscrypt:://' | \
      tr -d '\n' | \
      base64 -D
    ) \
    --output text \
    --query Plaintext | \
  base64 -D;
}

The kmse function takes an options argument which is the UUID of the key to use. Otherwise it uses the key specified in the KMS_KEY environment var. Both functions read /dev/stdin to get what needs to be encrypted/decrypted. Therefore, the following examples all work:

## Encrypting

$ tar -czf - /etc | kmse > etc.tgz.encrypted

$ kmse 77ed1d23-6013-47ce-b48a-2a968ef0ddaa < ~/.ssh/id_rsa > id_rsa.pem.encrypted

$ cat | kmse | netcat 10.0.0.123 8080
<content_pasted_from_my_clipboard>
^D

## Decrypting

$ kmsd < etc.tgz.encrypted | tar -zxf -

$ kmsd < id_rsa.pem.encrypted > ~/.ssh/id_rsa.pem

$ cat | kmsd | tee output.txt
<content_pasted_from_my_clipboard>
^D

# Note: ^D is a CTRL-D character that tells `cat` this is the End Of File.

While the cat paste CTRL-D is a cool trick. I have a script called cb that I use for getting data in and out of my clipboard via stdin and stdout. And it now works on Mac, Linux, Windows Cygwin, and Windows WSL! So, I can encrypt and decrypt what is in my clipboard with:

## Encrypt

$ cb | kmse | cb

## Decrypt

$ cb | kmsd | cb

A similar concept that is Mac OSX specific is:

## Encrypt

$ pbpaste | kmse | pbcopy

## Decrypt

$ pbpaste | kmsd | pbcopy