Encryption in AWS KMS

Learn encryption in AWS KMS in this tutorial by Zeal Vora, a DevSecOps engineer in defensive security.

Key management service

AWS KMS is a managed service that allows users to create and control the secret keys, which use HSM on the backend. In this approach, customers do not get a dedicated access to HSM and get something similar to a shared approach. This reduces the cost tremendously followed by the time and efforts spent to manage an HSM appliance.

AWS KMS brings a lot of benefits such as being very simple to use, provides built-in auditing, being low cost, and compliant against various standards, including FIPS 140, PCI DSS, and ISO 27001.

The cost of KMS depends on the API request that is being sent. There is no upfront cost, which makes it easily affordable for everyone.

The basic working of AWS KMS

In AWS KMS, the first step is to generate a Customer Master Key (CMK). This key is a symmetric key based on AES GCM 256 bits and will be used for encryption and decryption of data.

In the backend, the CMK is stored in HSM and the key is never shared with the user.

You can call the KMS API with the data that needs to be encrypted or decrypted and KMS will do it for you. This is further illustrated in the subsequent diagram.

Encrypting a function in KMS

The user sends some data to be encrypted to the KMS. In the backend, the KMS API interacts with some sort of implementation based on HSM appliances and you get the encrypted data back.

Decrypting a function in KMS

During the decryption process, the user sends the encrypted message back to the KMS. The KMS will coordinate with the backend servers, decrypt the data, and send the plaintext data back to the user.


Now that you know the basics of KMS and how it works, you can go ahead and generate your first KMS key and try out the encryption and decryption:

  1. Generate a customer master key: The first thing that needs to be done is to generate a customer master key. This key will be used for your encryption and decryption functionality. Inside the Identity and Access Management service, there is a tab called Encryption keys. By default, you’ll see that there are certain CMK pre-generated for various services. In order to generate your own CMK, you need to click on Create key:
  2. Fill in the details: Once you click on Create Key, you’ll be asked to fill in a certain set of details. You need to give a name associated with the key so that it will be easy for your reference. In your case, you will have an alias called kplabs. Click on Next
  3. Define the key administrators and key users: In this step, you can define who the administrator of the key will be. The Key Administratorswill be able to have control over the key permissions, including deletion of the key and also defining which users will be able to use this key for the encryption and decryption function. You can enter in the following users for the purpose of this article: 
  4. Define the key users: The key users are the ones who will be able to refer the key for encryption and decryption of data. You’ll need to select who will be allowed to use this key for the previous two functions: 
  5. View key details: Once these permissions are set, you’ll be ready to use these keys. You can find your key details on the KMS screen: 

Note that the actual key is stored in the HSM at the backend and you’ll never get the master key. In order to encrypt data, you need to refer the data to Key ID, and KMS will use the associated master key with this Key ID to encrypt and decrypt the data.

Practical guide

In the earlier section, you’ve added user zeal as a key user. In this section, you’ll use the access and secret keys for the user zeal for the encryption and decryption function.

You need to create a set of access keys and secret keys and have configured it on the local machine with the aws configure command. Make sure that you have the AWS CLI installed.

Configuring AWS CLI

Since you are working with AWS CLI, you’ll need to quickly configure the AWS keys. A better way is to use the IAM role if that is feasible:

 [root@kplabs ~]# aws configureAWS Access Key ID [None]: YOUR-ACCESS-KEY-HEREAWS Secret Access Key [None]: YOUR-SECRET-KEY-HEREDefault region name [None]: us-east-1Default output format [None]:

Once you’ve set up appropriate access and secret keys/IAM role with permission on KMS, you can go ahead and verify if you are able to list your KMS keys:

  1. Verify if the key listing is possible: Once you have the AWS CLI configured with a proper set of keys for user zeal, you can go ahead and verify the list of keys available:

zeal@kplabs:~# aws kms list-keys –region us-east-1

  1. Encryption function: In order to encrypt the data with the help of KMS CMK, you’ll need to reference the ARN of the KMS CMK that you’ve generated. You can get the ARN from the list-keysoperation that you ran in the previous step:

zeal@kplabs:~# aws kms encrypt –key-id arn:aws:kms:us-east-1:836802967410:key/85155cf0-f872-4cf8-bb0e-de9ab3e7ef18 –plaintext “This is kplabs book” –region us-east-1

In the previous screenshot, you can see that there are a lot of other things along with the ciphertext data. To top this, the ciphertext data that you see is base64 encoded. To get the ciphertext data associated with the plaintext, you can use this command:

 [root@kplabs ~]# aws kms encrypt –key-id arn:aws:kms:us-east-1:836802967410:key/85155cf0-f872-4cf8-bb0e-de9ab3e7ef18 –plaintext “This is kplabs book” –region us-east-1 –query CiphertextBlob –output text | base64 -d > encrypted.txt

  1. Cleaning the output: This will store the ciphertext in a file called txt. If you open the contents of the file with the catcommand, the output will be somewhat similar to the following screenshot: 

So, now you can see the real encrypted data, and if you observe, it is not really possible to read or decode plaintext from the encrypted output.

The decryption function

In order to decrypt the ciphertext stored in encrypted.txt, you can run this command:

aws kms decrypt –ciphertext-blob fileb://encrypted.txt –query Plaintext –output text | base64 -d 

With the previous command, you successfully decoded the plaintext value that you received from KMS with the help of base64 so that you can get the ideal text back.

However, one of the disadvantages of this approach is that AWS KMS allows encryption of only 4 KB of data with the help of CMK. In many cases, the data might be much larger and using this solution might not always work. In such cases, you can make use of envelope encryption.

If you’d like to explore more in the field of cloud security, you can refer to Zeal Vora’s Enterprise Cloud Security and Governance to build resilient cloud architecture to tackle data disasters with ease. This book has everything you need to secure your cloud environment with.

Leave a comment

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