Encrypting secrets with AWS KMS

Dani Hodovic March 12, 2018 1 min read
Responsive image

$ aws kms encrypt \
    --key-id $KMS_KEY
    --plaintext 'my-secret'
    --output text
    --query CiphertextBlob
    > ./secret

Encrypting a secret gives us a binary string that's base64 encoded. That's right, two levels of encoding.

$ aws kms decrypt
    --query Plaintext
    --output text
    --ciphertext-blob fileb://<(cat secret | base64 --decode)
    | base64 --decode

Decrypting a secret takes a binary string as input ([not a base64 encoded one!] (https://github.com/aws/aws-cli/issues/2063#issue-164963450)) and returns a base64 encoded string. That means that the output we got from aws kms encrypt needs to be base64 decoded to a binary string and fed into aws kms decrypt.

Breaking down the parameters:

  • aws decrypt --ciphertext-blob The secret in form of a binary string we want to decrypt.

  • aws encrypt --key-id The KMS key ID that we'll use to encrypt our secret.

  • --output text JSON is the default output format of the aws cli. If the cli returns a JSON string it will be quoted, e.g "my-secret". Providing the --output parameter strips the quotes from our string which is what we usually want.

  • --query CiphertextBlob By default the aws cli returns a JSON structure with the key and the secret. We only want the secret (CiphertextBlob) so we'll use query to filter the output.