AWS KMS basics, Encryption of EBS volumes, Attaching EC2 instances
What is Envelope Encryption? If you had a huge chunk of data to be encrypted and did not want to use your cloud encryption service (KMS) to encrypt the entire payload, what might be an option to still secure your data?
The answer lies in something called envelope encryption.
Instead of encrypting the payload with the cloud service, you encrypt the payload NORMALLY, with your own data key. What you do next is that you take your data key – and now pull in your cloud service to encrypt the data key.
The cloud service adds an additional layer of security to your encrypted payload. You would need an IAM user or role – with the appropriate KMS permissions (typically kms:encrypt and kms:decrypt) to allow an API call to the cloud service.
The important thing to remember is that the cloud service does TWO things :
- a) Provide you with a data key in case you don’t have one of your own (see How do I generate a data key? below)
- b) Provide you with an encrypted version of your data key – so you don’t actually need the data key once you are done with it (more on this below).
How do I generate a data key?
You make a KMS API call – generateDataKey.
The response of kms’s generateDataKey contains
{
"CiphertextBlob": blob,
"KeyId": "string",
"Plaintext": blob
}
The ciphertext is where the envelope encrypted data key is stored!
The ciphertext is where the envelope encrypted data key is stored! This is what allows you to effectively discard the data key altogether.
Can I use KMS to encrypt my data with the data key I just generated?
Not directly, No!
You cannot use KMS to do anything directly with your data key. It was not designed for using your data key. You have to use an external method to leverage your data key to encrypt data.
I reiterate this multiple times because this is one of the most frequent misconceptions around KMS. When you make an encrypt call in KMS, you are NOT encrypting the payload. All you are encrypting is your data key. From AWS’ own documentation
KMS cannot use a data key to encrypt data.
However, AWS KMS DOES let you GENERATE a data key that you can use outside of KMS, such as by using OpenSSL or a cryptographic library like the AWS Encryption SDK.
What happens when I use KMS for EBS encryption?
AWS KMS generates a new data key (generateDataKey), envelope encrypts it and then sends the envelope encrypted data key to Amazon EBS.
This envelope encrypted package is stored alongside the EBS volume metadata.
How do I use this EBS volume with an EC2 instance?
When you attach the encrypted volume to an EC2 instance, Amazon EC2 sends the encrypted data key to AWS KMS with a Decrypt request. This allows the EC2 to decrypt the enveloped data key.
The user or role starting the EC2 instance, needs to also have access to KMS (specifically kms:decrypt permission).
Without this, the EC2 instance will fail to start. Once the EC2 instance is up and running, anyone with access to the EC2 instance will have access to the EBS volume. Only the decrypted data is presented to the user.
Summary
KMS is a great service if you remember what it is meant for – and what is NOT meant for.
It is NOT meant to encrypt large payloads of data, which you would still do using alternative means (openssl etc.)
KMS IS designed to specifically encrypt small volumes of data (less than 4KB) – in particular, this makes it useful for encrypting other data keys. When used in combination with another regular encryption mechanism (e.g. AES 256 symmetric encryption), it makes for a full end to end protection solution.
Not only would you need the plaintext data key to get to the encrypted payload, you would also need IAM access to AWS (specifically a kms:decrypt permission ). This adds a second layer of security on top of the AES encrypted EBS volume. In fact, an EC2 instance with such an EBS volume attached, will refuse to start unless granted the appropriate kms:decrypt permissions.
Are you using KMS in your project? Do you have any interesting observations? Questions?
Leave a Reply