Security in The Cloud: Encryption On AWS (Part 1: KMS)
Tags: security, encryption, cloudnative, aws
Published: 2022-10-31 23:26:02

Security and Compliance is a shared responsibility between you and your cloud provider. No one party can abandon the full responsibility to the other. Depending on the service you are utilizing your cloud provider operates, manages and controls the components from the host operating system and virtualization layer down to the physical security of the facilities in which the service operates. 

You on the other hand assumes responsibility and management of the guest operating system (including updates and security patches), other associated application software as well as the configuration of the cloud provided security group firewall. 

To this effect you should carefully consider the services you choose as your responsibilities vary depending on the services used, the integration of those services into your IT environment, and applicable laws and regulations. Your security responsibility is what is referred to as **Security in the Cloud**

The hands on security method we would be working with today is encryption in AWS. This hands on is designed to help you achieve familiarity with the various ways of encrypting your data and resources in the AWS services you use.

### Requirements
- An AWS account 
- The AWS CLI set up in your local machine. Here's a guide on how to 
[setup AWS CLI access](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html).
- You need IAM User credentials  with permissions for KMS (e.g. the AWSKeyManagementServicePowerUser  managed policy)

### WHAT IS AWS KMS

Encryption is a crucial part of a sound data protection plan,  People frequently believe they must learn complex technologies to encrypt data, but this is not the case as it can be made simpler by the cloud.

The primary way to control access to your data is called access control. Encryption allows you to introduce an additional authorization condition before granting access to data. 

AWS KMS is an AWS fully managed, centralized key management service that is integrated with other AWS services. AWS Key Management Service makes it simple to manage encoding keys used to encode data kept by the user applications in spite of wherever the user store it. It is integrated with AWS CloudTrail to supply the user with logs of API calls created to or by KMS. These logs assist the user to meet compliance and regulative necessities by providing details of use of your CMKs, when they were accessed, who accessed them and where they were used.

When you encrypt using AWS KMS , you can get further control over access to sensitive data. For example, with S3 objects that are encrypted by KMS, each IAM user must not only have access to the storage itself but also have authorization to use the KMS key that protects the data.

### What are your data protection needs?
Depending on what your need is, there are various services and approaches available to you when it comes to encryption.

Take a look at the list below:

- Do you need to create and manage the hardware security modules that store your encryption keys? Consider the **AWS CloudHSM  service**.

- Would you benefit from an AWS service  that protects your encryption keys for you? Consider **AWS Key Management Service (AWS KMS)**.

- Do you need to protect your data before you send it to AWS? Use a client-side encryption library, like the **AWS Encryption SDK** , the **DynamoDB Encryption Client** , or **Amazon S3 client-side encryption**.

### WHAT ARE CMKs
Customer master keys (CMK ) are the primary resources in AWS KMS. A customer master key is a logical representation of a master key. The CMK includes metadata such as the key ID, creation date, description, and key state. The CMK also contains the key material used to encrypt and decrypt data.

You can use CMKs to generate, encrypt, and decrypt the data keys that you use outside of AWS KMS to encrypt your data. This is known as envelope encryption. CMKs can be:

- **Customer-managed:** These are created and managed by the AWS user. Access to it can be controlled using the AWS IAM service
- **AWS-managed:** These are created and managed by AWS on your behalf. They can be identified by the format aws/service-name
- **AWS-owned:** These are not in your AWS account. They are part of a collection of CMKs that AWS owns and manages for use in multiple AWS accounts. They cannot be viewed or managed by the user

## Envelope Encryption
A CMK can be used to encrypt up to 4kB of data. Which is more than enough for a database password, but what about larger amounts of data? That's where the Envelope Encryption comes in.


### Confirm your AWS CLI is Working Correctly
You can run a quick test to see if your AWS CLI is properly configured by running this command to retrieve a list of KMS keys from your account:

```powershell
aws kms list-keys
```
If you have never used the AWS CLI, here's a guide to [download and install the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html) and [configure your profile on the CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html) 

### Creating a CMK
First, we create a CMK, which we will use to encrypt and decrypt our data key. Using the code below:

```powershell
aws kms create-key --description "KMS lab - envelope encryption CMK"
```
![AWS KMS Envelope Encryption](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mkqiewgk16lyldsninbm.PNG)

Note the KeyId for later when we want to delete resources.

![AWS KMS Envelope Encryption](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lsjk9qhjf1wrztd9f9m8.PNG)

We would Create an alias for the CMk, to make it easier to work with:

```powershell
aws kms create-alias --target-key-id <your KeyId from the above step> --alias-name alias/demo-lab-cmk
```
The CMK we have just created will not be used to encrypt our data since we are doing envelope encryption; rather, this will be used to encrypt another key, that we can then use locally to protect our sensitive data.

You can confirm all the changes made so far from the AWS management console. We can see our new key, search for KMS and navigate to it, on the left side select customer managed keys and you will see the key we just created.


![AWS KMS Envelope Encryption](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fs00z6j8tolsc5av9r1h.PNG)

### Generating a Data Key

Like we earlier stated, we don't use our CMK to encrypt our data so now, let's ask KMS to generate a data key using our CMK; this is the key we will actually use to encrypt and decrypt our sensitive data: 

```powershell
aws kms generate-data-key --key-id alias/demo-lab-cmk --key-spec AES_256
```
The output should look like


![AWS KMS Envelope Encryption](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h4co9fksp5ydoemfgl10.PNG)

The fields to take note of (as we would be using them soon) are:

- CiphertextBlob - The data key, encrypted with the demo-lab-cmk CMK. This is what you will store persistently in order to decrypt and encrypt in future
- Plaintext - The data key, unencrypted. We could use this straightaway to encrypt some data, if we wanted to.

### Decode Base64 Data Keys (Plaintext and CiphertextBlob)

The output is both the CipherTextBlob and the Plaintext are in a base64 encoded pattern. When you use the KMS at the command line like we've been doing so far, you're essentially always working with base64 encoded.

Use a command like the one below, where the argument for "echo" command is the plaintext key obtained when creating data key. The output file name will be datakeyPlainText.txt.

```powershell
echo '<your plaintext from the previous step>' | base64 --decode > datakeyPlainText.txt

echo '<your CipherTextBlob from the previous step>' | base64 --decode > datakeyEncrypted.txt
```
### Encrypt Data Using Plaintext Data Key

It's time to encrypt some actual data, we will echo a text and encrypt it using AES256 bits with the data key in Plaintext stored in file "datakeyPlainText.txt" and save the encrypted output to file "encryptedSecret.txt". 

```powershell
echo "Hi there! You are about to witness the magic of encryption." | openssl enc -e -aes256 -k file//./dataKeyPlainText.txt > ./encryptedSecret.txt
```

![AWS KMS Envelope Encryption](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hwbfet6m8jn22uspbeaf.PNG)

We have our text now encrypted in the file encryptedSecret.txt. You can do a "more" or "cat" operation over it. You will notice the encryption. The original text is not recognizable.

```powershell
cat encryptedSecret.txt
```

![AWS KMS Envelope Encryption](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g9ubwd6j51o3k812hee2.PNG)

We now have our encrypted data and our encrypted data key and we can store then together or store them, separately.

### Delete Plaintext Data Key
Following security best practices we will delete our Data key from our computer as it's sensitive information and we don't require it anymore after carrying out our encryption.

When we need to decrypt we will use our saved Encrypted Data key thereby reobtaining the plaintext data key.

```powershell
rm datakeyPlainText.txt
```
## Decrypting the encrypted secret text
Remember we already deleted our plain text data key, therefore we will need to carry out several steps before decrypting our secret.

Using the encrypted data key that was provided to us when calling the AWS KMS generate data key operation which we stored as b64 decoded in file datakeyEncrypted.txt we will decrypt the data key with the appropriate Master Key (CMK) that was used to encrypt it.

### Decrypt Encrypted Data Key

The command we will use here is the aws decrypt command. This command will tell AWS KMS to revert the encryption made over the data key.

We don´t need to provide the KeyId that was used to encrypt the data key, the encrypted data contains metadata to provide this information to AWS KMS.

```powershell
aws kms decrypt --ciphertext-blob fileb://datakeyEncrypted.txt
```

![AWS KMS Envelope Encryption](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pwxqiqqzxremhw5jzo5q.PNG)

### Decode Base64 encoded Plaintext Data Key

Next we will decode it from base64 and use it to decrypt the encrypted secret file, encryptedSecret.txt. Again using the OpenSSL library: Copy the plaintext key and use it as an input to "echo", as you can see below.

```powershell
echo '<your plaintext from the previous step>' | base64 --decode > datakeyPlainText.txt
```
### Decrypt secret Using Plaintext Data Key
Now that we have the data key in Plaintext and decoded from base64, let's decrypt

```powershell
cat encryptedSecret.txt | openssl enc -d -aes256 -k file//./dataKeyPlainText.txt > ./PlaintextSecret.txt
```

![AWS KMS Envelope Encryption](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qqtqota6c2m3fzq9aofe.PNG)

You can confirm that you have the original text back with the cat command.

```powershell
cat PlaintextSecret.txt
```

![AWS KMS Envelope Encryption](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sb0xugz2ek233ze34s65.PNG)

You now have an idea how envelope encryption works.

The data to be encrypted and decrypted by your applications would use envelope encryption in a similar way. It is a powerful mechanism, enabled by AWS KMS CMKs, to protect in two tiers, the integrity and confidentiality of your data.

In subsequent posts in this series we will see how it applies for AWS services working with AWS KMS.

### Cleaning up

Deleting an AWS KMS key is destructive and potentially dangerous. It deletes the key material and all metadata associated with the KMS key and is irreversible. After a KMS key is deleted, you can no longer decrypt the data that was encrypted under that KMS key, which means that data becomes unrecoverable. You should delete a KMS key only when you are sure that you don't need to use it anymore. If you are not sure, consider disabling the KMS key instead of deleting it. You can re-enable a disabled KMS key if you need to use it again later, but you cannot recover a deleted KMS key.

You can only schedule the deletion of a customer managed key. You cannot delete AWS managed keys or AWS owned keys.
This is how you can delete all resources created on this page

**Delete the alias of the CMK**

```powershell
aws kms delete-alias --alias-name alias/demo-lab-cmk
```

**We then schedule the CMK for deletion in 7 days after executing the command**

```powershell
aws kms schedule-key-deletion --key <YOUR_CMK_KEY_ID> --pending-window-in-days 7
```