AWS Security Blog

How to Encrypt and Decrypt Your Data with the AWS Encryption CLI

August 31, 2021: AWS KMS is replacing the term customer master key (CMK) with AWS KMS key and KMS key. The concept has not changed. To prevent breaking changes, AWS KMS is keeping some variations of this term. More info


AWS KMS image

You can now encrypt and decrypt your data at the command line and in scripts—no cryptography or programming expertise is required. The new AWS Encryption SDK Command Line Interface (AWS Encryption CLI) brings the AWS Encryption SDK to the command line.

With the AWS Encryption CLI, you can take advantage of the advanced data protection built into the AWS Encryption SDK, including envelope encryption and strong algorithm suites, such as 256-bit AES-GCM with HKDF. The AWS Encryption CLI supports best-practice features, such as authenticated encryption with symmetric encryption keys and asymmetric signing keys, as well as unique data keys for each encryption operation. You can use the CLI with customer master keys (CMKs) from AWS Key Management Service (AWS KMS), master keys that you manage in AWS CloudHSM, or master keys from your own custom master key provider, but the AWS Encryption CLI does not require any AWS service.

The AWS Encryption CLI is built on the AWS Encryption SDK for Python and is fully interoperable with all language-specific implementations of the AWS Encryption SDK. It is supported on Linux, macOS, and Windows platforms. You can encrypt and decrypt your data in a shell on Linux and macOS, in a Command Prompt window (cmd.exe) on Windows, or in a PowerShell console on any system.

In this blog post, I walk you through the process of using the AWS Encryption CLI to encrypt and decrypt a file. You can find more examples of using the new CLI and detailed instructions for installing and configuring the CLI in the AWS Encryption SDK Developer Guide. You are also welcome to participate in the development of the AWS Encryption CLI (aws-encryption-sdk-cli) on GitHub.

Encrypt a file

Let’s use the AWS Encryption CLI to encrypt a file called secret.txt in your current directory. I will write the file of encrypted output to the same directory. This secret.txt file contains a Hello World string, but it might contain data that is critical to your business.

$ ls
secret.txt

$ cat secret.txt
Hello World

I’m using a Linux shell, but you can run similar commands in a macOS shell, a Command Prompt window, or a PowerShell console.

When you encrypt data, you specify a master key. This example uses an AWS KMS CMK, but you can use a master key from any master key provider that is compatible with the AWS Encryption SDK. The AWS Encryption CLI uses the master key to generate a unique data key for each file that it encrypts.

If you use an AWS KMS CMK as your master key, you need to install and configure the AWS Command Line Interface (AWS CLI) so that the credentials you use to authenticate to AWS KMS are available to the AWS Encryption CLI. Those credentials must give you permission to call the AWS KMS GenerateDataKey and Decrypt APIs on the CMK.

The first line of this example saves an AWS KMS CMK ID in the $keyID variable. The second line encrypts the data in the secret.txt file. (The backslash, “\”, is the line continuation character in Linux shells.)

To run the following command, substitute a valid CMK identifier for the placeholder value in the command.

$ keyID = "111122223333"
$ aws-encryption-cli --encrypt --input secret.txt \
                     --master-keys key=$keyID \
                     --encryption-context purpose=test \
                     --metadata-output ~/metadata \
                     --output .

This command uses the --encrypt (-e) parameter to specify the encryption action and the --master-keys (-m) parameter with a key attribute to specify an AWS KMS CMK. If you’re not using an AWS KMS CMK, you need to include a provider attribute that identifies the master key provider.

The command uses the --encryption-context parameter (-c) to specify an encryption context, purpose=test, for the operation. The encryption context is non-secret data that is cryptographically bound to the encrypted data and included in plaintext in the encrypted message that the CLI returns. Providing additional authenticated data, such as an encryption context, is a recommended best practice.

The --metadata-output parameter tells the AWS Encryption CLI where to write the metadata for the encrypt command. The metadata includes the full paths to the input and output files, the encryption context, the algorithm suite, and other valuable information that you can use to review the operation and verify that it meets your security standards.

The --input (-i) and --output (-o) parameters are required in every AWS Encryption CLI command. In this example, the input file is the secret.txt file. The output location is the current directory, which is represented by a dot (“.”).

When the --encrypt command is successful, it creates a new file that contains the encrypted data, but it does not return any output. To see the results of the command, use a directory listing command, such as ls or dir. Running an ls command in this example shows that the AWS Encryption CLI generated the secret.txt.encrypted file.

$ ls
secret.txt  secret.txt.encrypted

By default, the output file that the --encrypt command creates has the same name as the input file, plus a .encrypted suffix. You can use the --suffix parameter to specify a custom suffix.

The secret.txt.encrypted file contains a single, portable, secure encrypted message. The encrypted message includes the encrypted data, an encrypted copy of the data key that encrypted the data, and metadata, including the plaintext encryption context that I provided.

You can manage an encrypted file in any way that you choose, including copying it to an Amazon S3 bucket or archiving it for later use.

Decrypt a file

Now, let’s use the AWS Encryption CLI to decrypt the secret.txt.encrypted file. If you have the required permissions on your master key, you can use any version of the AWS Encryption SDK to decrypt a file that the AWS Encryption CLI encrypted, including the AWS Encryption SDK libraries in Java and Python.

However, you cannot use other tools, such as the Amazon S3 encryption client or the Amazon DynamoDB encryption client, to decrypt the encrypted message because they use an incompatible encrypted message format.

The following command decrypts the contents of the secret.txt.encrypted file.

$ aws-encryption-cli --decrypt --input secret.txt.encrypted \
                     --encryption-context purpose=test \
                     --metadata-output ~/metadata \
                     --output .

The --decrypt command requires an encrypted message, like the one that the --encrypt command returned, and both --input and --output parameters.

This command has no --master-keys parameter. A --master-keys parameter is required only if you’re not using an AWS KMS CMK.

In this example command, the --input parameter specifies the secret.txt.encrypted file. The --output parameter specifies the current directory, which again is represented by a dot (“.”).

The --encryption-context parameter supplies the same encryption context that was used in the encrypt command. This parameter is not required, but verifying the encryption context during decryption is a cryptographic best practice.

The --metatdata-output parameter tells the command where to write the metadata for the decrypt command. If the file exists, this parameter appends the metadata to the existing file. The AWS Encryption CLI also has parameters that overwrite the metadata file or suppress the metadata.

When it is successful, the decrypt command generates the file of decrypted (plaintext) data, but it does not return any output. To see the results of the decryption command, use a command that gets the content of the file, such as cat or Get-Content.

$ ls
secret.txt  secret.txt.encrypted  secret.txt.encrypted.decrypted

$ cat secret.txt.encrypted.decrypted
Hello World

The output file that the --decrypt command created has the same name as the input file, plus a .decrypted suffix. The --suffix parameter works on --decrypt commands, too.

Encrypt directories and more

In addition to encrypting and decrypting a single file, you can use the AWS Encryption CLI to encrypt and decrypt strings that you pipe to the CLI, and all or selected files in a directory and its subdirectories, or local or remote volumes. We have examples for you to try in the AWS Encryption SDK documentation.

The new AWS Encryption CLI also supports more advanced features of the AWS Encryption SDK, including alternate algorithm suites, alternate Python-based master key providers, encryption with multiple master keys, encrypting streamed data, creating encrypted messages with custom frame sizes, and data key caching.

For more information about the AWS Encryption CLI, see the AWS Encryption SDK Developer Guide and the full documentation. If you have questions about the AWS Encryption CLI, file an issue in the aws-encryption-sdk-cli repository on GitHub, or read and post on the AWS Crypto Tools Discussion Forum.

– June

Want more AWS Security how-to content, news, and feature announcements? Follow us on Twitter.