This would have saved me an hour or two, so I’m posting it here for posterity. 🙂 Maybe it will save some time for someone else.
A quick example of how to use the AWS CLI to encrypt a file using a KMS with a key identified by the `key-id`. The output is saved into 76-column wrapped ASCII-armored file, and then decrypt the same back into cleartext. I couldn’t find a way to column-wrap the output from `aws kms encrypt`, so the base64 encoding is first undone, and then re-applied with the [default] column width of 76.
Replace the below fake `key-id` with your own (obviously 🙂 ) that your AWS credentials have access to. For this to work, you have to have awscli installed and configured (run `aws configure` after you’ve installed `awscli`).
** NOTE: On macOS, you have to use capital `-D` with `base64` to decrypt.
First, to encrypt the contents of a file, and then output the decrypted content back into a file, use the following format:
aws kms encrypt --key-id 3c436c82-eabe-4b58-996f-6ca3f808f237 --plaintext fileb://my-secret-key.pem --query CiphertextBlob --output text | base64 -d | base64 -w 76 > encrypted.asc
aws kms decrypt --ciphertext-blob fileb://<(cat encrypted.asc | base64 -d) --output text --query Plaintext | base64 -d > decrypted.txt
Then, to encrypt/decrypt a string without first saving it into a file (who came up with the decryption format?!). This works in `bash`, `zsh`, and alike (`ksh`..?):
aws kms encrypt --key-id 3c436c82-eabe-4b58-996f-6ca3f808f237 --plaintext 'Secret message' --query CiphertextBlob --output text
aws kms decrypt --ciphertext-blob fileb://<(echo 'AQECAHiuImqexTQGWMAtOjKMcH5UIxXuSZ5WSGx3WKO+vsUI3AAAAKIwgZ8GCSqGSIb3DQEHBqCBkTCBjgIBADCBiAYJKoZIhvcNAQcBMB4GCWCGSAFlAwQBLjARBAwT3cwVGtUYHz02irsCARCAW8a4TP7pL+inl7Je7x1xEr84Q4lN11t3dNFvycpMZALe185DYow4i1GLaJnJnB7g6V1ZaiB+b+Diap/5auM/K3bjLmcTq0molBnn2TG3r0uj70lP0FSQP+XwQ+8=' | base64 -d) --output text --query Plaintext | base64 -d
Finally, if you want to enter the encrypted content into a JSON structure, simply leave the `base64` undo/redo out, and change the output type to JSON, like so:
aws kms encrypt --key-id 3c436c82-eabe-4b58-996f-6ca3f808f237 --plaintext fileb://my-secret-key.pem --query CiphertextBlob --output json
Without redirection both the encrypt and decrypt commands output to standard output (as in the first example).
Hi,
Thank you for the wonderful blog.
When i run the above command for encrypt, im getting “base64: invalid input” error.
When i removed all reference to base64, it succeeded.
But when running decrypt( also without base64), im getting error “An error occurred (InvalidCiphertextException) when calling the Decrypt operation:”
KIndly help. I’m a newbie to AWS.
Hi Jinet,
You may have an old version of base64. See this StackOverflow answer for a possible explanation.
Also note that depending on the system, the decrypt switch may be `-d` (at least Linux distros), or `-D` (at least macOS).
Change the –output to text instead of json
Helped out a bunch. Thanks.
One question is is it possible to encrypt once and use in multiple regions?
@John Parker
Late answer, but in case you or someone else reading this is wondering, AWS introduced cross-region replication with KMS in November of last year. See the following article for details:
New Amazon S3 Encryption & Security Features
This saved me 3 hours, so:
Thank You!
Thank You!
Thank You!
@John Parker
Apparently not. AWS support responds in a 2014 blog post:
Hi Thanks
fileb://my-secret-key.pem : not understanding what is this my-secret-key.pem
Please let me know
Hi @AJIT
It is a placeholder for the secret file name for the file you want to encrypt. In other words, in this example a file (located in the current directory) named:
.. is being encrypted with KMS.
.. is actually an indicator that you’re passing a file. See more info here.
Thank you very much Ville,
I’m adding myself to those who saved a couple of hours thanks to this post!
Have a fantastic day and if you have a BTC address I’ll be happy to buy you a drink : )
Cheers
Fabio
Actually better some other altcoin with low transaction fees 🙂
Hi Fabio! Glad the post was helpful! 🙂
Gotta set up some altcoins (it’s on my todo list..). Thus far I’ve got just Bitcoin and Z-Coin set up (https://keybase.io/vwal). Which ones do you recommend?
Hi Ville,
a good way to say up to date on this is to look at https://www.coinmarketcap.com and keep an eye on the fist 10 🙂
A good wallet that allows you to get set up quickly with many is https://www.exodus.io/
Good luck with everything!
Fabio
Awesome… thanks for this post!!
I think it is worth mentioning that KMS only supports files with 4KB (4096 bytes) maximum size
Hi @Daniel! Yes, that’s a good point! Anyone who needs to encrypt larger than 4KB files should look into envelope encryption with KMS. There are many articles about it on the web.
Cheers — this was a very handy note to find, as I was beating my head against how to decrypt something I’d KMS encrypted into JSON.
I expanded on your examples and made encrypt and decrypt functions that use stdin and stdout. I go into detail in this StackOverflow answer: https://stackoverflow.com/a/53735748/117471