A Simple AWS CLI KMS encrypt/decrypt example

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).

17 thoughts on “A Simple AWS CLI KMS encrypt/decrypt example”

  1. 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.

  2. Helped out a bunch. Thanks.

    One question is is it possible to encrypt once and use in multiple regions?

  3. @John Parker

    Apparently not. AWS support responds in a 2014 blog post:

    KMS is designed so that keys can only be used in the region in which they were created. This design helps improve the security of the keys because they cannot be exported from the regional service. We are not currently planning to support replication of keys across regions. KMS is built with redundant systems to provide high availability and durability of your keys within a region. In order to improve the availability of your data, you can choose to encrypt copies of your data in multiple regions. Data in a given region would be encrypted under a unique master key in KMS.

    1. 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:

      my-secret-key.pem

      .. is being encrypted with KMS.

      fileb://

      .. is actually an indicator that you’re passing a file. See more info here.

  4. 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

  5. Awesome… thanks for this post!!
    I think it is worth mentioning that KMS only supports files with 4KB (4096 bytes) maximum size

  6. 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.

Leave a Reply to Daniel Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.