Amazon Web Services – AWS Key Management Service Best Practices Page 1 Introduction AWS Key Management Service (AWS KMS) is a managed service that makes it easy for you to create and control the encryption keys used to encrypt your data. AWS KMS uses Hardware Security Modules (HSMs) to protect the security of your keys. 1 You can use AWS KMS. We are going to create a KMS key that will be used to encrypt and decrypt our secret parameter/s. From your terminal, run the following command, which will create a KMS key. $ /demo/kms-ssm-decrypt (venv) aws kms create-key -description 'A key to encrypt-decrypt secrets' 'KeyMetadata': 'AWSAccountId. More from Towards Data Science. Mar 02, 2020 AWS Key Management Service – KMS. AWS KMS is a managed encryption service that allows creation and control of encryption keys to enable encryption of data easily; KMS provides a highly available key storage, management, and auditing solution to encrypt the data across AWS services & within applications.
AWS KMS then uses the specified CMK to generate data keys. As you can see from the below figure it generates one plaintext data key and an encrypted data key. This plaintext data key is used to encrypt the data, then the plaintext key is removed ASAP from the memory so that data doesn’t get compromised. AWS services and client-side toolkits that integrate with AWS KMS use a method known as envelope encryption to protect your data. Under this method, AWS KMS generates data keys which are used to encrypt data locally in the AWS service or your application.
[ aws . kms ]
Description¶
Generates a unique symmetric data key. This operation returns a plaintext copy of the data key and a copy that is encrypted under a customer master key (CMK) that you specify. You can use the plaintext key to encrypt your data outside of AWS KMS and store the encrypted data key with the encrypted data.
To generate a data key, specify the symmetric CMK that will be used to encrypt the data key. You cannot use an asymmetric CMK to generate data keys. To get the type of your CMK, use the DescribeKey operation.
You must also specify the length of the data key. Use either the KeySpec or NumberOfBytes parameters (but not both). For 128-bit and 256-bit data keys, use the KeySpec parameter.
If the operation succeeds, the plaintext copy of the data key is in the Plaintext field of the response, and the encrypted copy of the data key in the CiphertextBlob field.
To get only an encrypted copy of the data key, use GenerateDataKeyWithoutPlaintext . To generate an asymmetric data key pair, use the GenerateDataKeyPair or GenerateDataKeyPairWithoutPlaintext operation. To get a cryptographically secure random byte string, use GenerateRandom .
You can use the optional encryption context to add additional security to the encryption operation. If you specify an EncryptionContext , you must specify the same encryption context (a case-sensitive exact match) when decrypting the encrypted data key. Otherwise, the request to decrypt fails with an InvalidCiphertextException. For more information, see Encryption Context in the AWS Key Management Service Developer Guide .
The CMK that you use for this operation must be in a compatible key state. For details, see How Key State Affects Use of a Customer Master Key in the AWS Key Management Service Developer Guide .
We recommend that you use the following pattern to encrypt data locally in your application:
- Use the GenerateDataKey operation to get a data encryption key.
- Use the plaintext data key (returned in the Plaintext field of the response) to encrypt data locally, then erase the plaintext data key from memory.
- Store the encrypted data key (returned in the CiphertextBlob field of the response) alongside the locally encrypted data.
To decrypt data locally:
- Use the Decrypt operation to decrypt the encrypted data key. The operation returns a plaintext copy of the data key.
- Use the plaintext data key to decrypt data locally, then erase the plaintext data key from memory.
See also: AWS API Documentation
See 'aws help' for descriptions of global parameters.
Synopsis¶
Options¶
--key-id (string)
Identifies the symmetric CMK that encrypts the data key.
To specify a CMK, use its key ID, Amazon Resource Name (ARN), alias name, or alias ARN. When using an alias name, prefix it with 'alias/' . To specify a CMK in a different AWS account, you must use the key ARN or alias ARN.
For example:
- Key ID: 1234abcd-12ab-34cd-56ef-1234567890ab
- Key ARN: arn:aws:kms:us-east-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
- Alias name: alias/ExampleAlias
- Alias ARN: arn:aws:kms:us-east-2:111122223333:alias/ExampleAlias
To get the key ID and key ARN for a CMK, use ListKeys or DescribeKey . To get the alias name and alias ARN, use ListAliases .
--encryption-context (map)
Specifies the encryption context that will be used when encrypting the data key.
An encryption context is a collection of non-secret key-value pairs that represents additional authenticated data. When you use an encryption context to encrypt data, you must specify the same (an exact case-sensitive match) encryption context to decrypt the data. An encryption context is optional when encrypting with a symmetric CMK, but it is highly recommended.
For more information, see Encryption Context in the AWS Key Management Service Developer Guide .
Shorthand Syntax:
JSON Syntax:
--number-of-bytes (integer)
Specifies the length of the data key in bytes. For example, use the value 64 to generate a 512-bit data key (64 bytes is 512 bits). For 128-bit (16-byte) and 256-bit (32-byte) data keys, use the KeySpec parameter.
You must specify either the KeySpec or the NumberOfBytes parameter (but not both) in every GenerateDataKey request.
--key-spec (string)
Aws Kms Generatedatakey
Specifies the length of the data key. Use AES_128 to generate a 128-bit symmetric key, or AES_256 to generate a 256-bit symmetric key.
You must specify either the KeySpec or the NumberOfBytes parameter (but not both) in every GenerateDataKey request.
Possible values:
- AES_256
- AES_128
--grant-tokens (list)
A list of grant tokens.
Microsoft word 2013 serial key generator. For more information, see Grant Tokens in the AWS Key Management Service Developer Guide .
Syntax:
--cli-input-json (string)Performs service operation based on the JSON string provided. The JSON string follows the format provided by --generate-cli-skeleton. If other arguments are provided on the command line, the CLI values will override the JSON-provided values. It is not possible to pass arbitrary binary values using a JSON-provided value as the string will be taken literally.
--generate-cli-skeleton (string)Prints a JSON skeleton to standard output without sending an API request. If provided with no value or the value input, prints a sample input JSON that can be used as an argument for --cli-input-json. If provided with the value output, it validates the command inputs and returns a sample output JSON for that command.
See 'aws help' for descriptions of global parameters.
Output¶
CiphertextBlob -> (blob)
Plaintext -> (blob)
KeyId -> (string)
Aws Kms Key Deletion
Encryption is an integral part of the AWS KMS operations and its interactions with other AWS services. In this section we are going to get a better understanding of it and make some hands-on practices. AWS KMS mostly uses envelope encryption, but can also encrypt data directly without envelope encrytion.
Envelope encryption is the main encryption vehicle for AWS services using AWS KMS.
The section is divided in the following parts:
How Envelope Encryption works in practice
AWS KMS is able to encrypt and decrypt up to 4 kilobytes (4096 bytes) of data. With other volumes of data, normally you will use a data key to perform encryption operations outside KMS through envelope encryption.Envelope encryption refers to the practice of protecting the data by encrypting it with a data key, and encrypting the data key itself with another encryption key, a CMK under KMS in this case.See the following figure from AWS KMS documentation.
<Figure-1>
AWS KMS is also capable of generating data keys to encrypt data from CMKs.NOTE: Data keys are only generated by AWS KMS, not stored or used to encrypt by AWS KMS itself.
Data keys are very different from a CMK, which never leaves AWS KMS and is only used in memory. Besides, data keys can be obtained in plain text or encrypted.
Once the data is encrypted and stored with a data key, the data key is stored encrypted with the data itself, while the plaintext version of the data key is deleted (for security best practices).
Therefore, to decrypt the data, the CMK needs to decrypt the encrypted data key and then, with the data key in plain text, the decrypt operation can take place.This adds a tier of protection to your data and better manageability. If a data key is compromised, only the service or data using that particular data key is compromised, no other data. If only one key was used for all data encryption across the platform and it gets compromised, the whole platform data would be also compromised.
Let's see envelope encryption in action with AWS KMS.
Step 1 - Create the secret text
First thing we will do is to create a file with the data we want to encrypt under envelop encryption. A sample 'secret' text file in this case with the text 'Sample Secret Text to Encrypt'.
Step 2- Generate the data key
Next, we ask AWS KMS to generate a data key referencing a CMK. The CMK is referenced to encrypt the data key. We will use the CMK created with our key material, this is the material we imported, key alias is 'ImportedCMK'. Use the following command to generate a symmetric data key with 256 bits length encrypted with our CMK.
You will notice that the command will fail to run. Our current Role with Power User permissions does not have enough privileges to generate a data key. As per least privilege best practices, we are providing permissions as needed in policies attached to the role that can be easily tracked and detached when such permission for that user is not needed any more.
We need to provide with permission to generate a data key.
The process is the same as we have seen twice in the previous section of the workshop, please go back to it if you need to in the following link: 'Create the import material and encrypt it for the import'
Basically, you need to go back to the AWS console, in the services area navigate to IAM and go to 'Policies'. We are going to create a new policy and attach it to the Power user role.
As we did in the previous section, click on new 'Create Policy', Select KMS as the service, go to the Actions area.In the 'Write' section, select 'GenerateDataKey' operation. Additionally select 'Encrypt', 'Decrypt' and the tagging operations as you can see in image below, we will need them for the nexts steps. and 'Any' as resource.
<Figure-1>
Click on 'Review Policy' and then give the policy a name, for example 'KMSWorkshop-AdditionalPermissions'.
You can click now in 'Create Policy'. Once created, attach it to the role KMSWorkshop-InstanceInitRole.
Once the policy is attached, if you try the same command again, it will succeed now. The command will return a JSON output with:
- the plaintext data key - Plaintext key in b64 encoding
- the KeyId used to encrypt plaintext data key
- A CiphertextBlob which is the encrypted data key generated, in base64 enconding.
Write these values down, we are going to needed them shortly.
Please note the command used a new parameter: 'encryption-context'. This is an optional key-pair value that provides additional context about the data and that needs to be provided as well when decrypting the data. This is because, when provided, it is bound to the cryptographic operation.
Encryption Context, besides helping with the integrity of the encrypted data, it has many other uses. For example: use it to set policies, to provide Grants or to monitor encrypt/decrypt operations in CloudTrail (will see later in this section).See additional information about encryption context in this part of the AWS KMS documentation.
Step 3 - Encrypt the secret text
We have now a data key 256 bit length that we can use to encrypt. We can use any encryption tool or library with the data key we have created to encrypt our data. ** Remember that AWS KMS does not store or use the data key for encryption **.
Let's use OpenSSL library to encrypt the sample file we want to be secret with our newly created data key.
We need to decode the plaintext data key we obtained above (Plaintext), as it is in b64, and store it in a file.
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.
We wil do the same for the encrypted plaintext (the CipherTextBlob) we have obtained when creating data key. Therefore, the argument for 'echo' command is the CipherTextBlob value of the data key genetarion's JSON output. We wil save it and save it in a file name datakeyEncrypted.txt:
Now we are ready to encrypt the file with the text we want to keep secret. Remember we stored the text in the file samplesecret.txt. For the job, we will use the OpenSSL library again, encrypting with AES256:
This command encrypts in AES256 bits the input file 'samplesecret.txt', with the data key in Plaintext stored in file 'datakeyPlainText.txt' and saves the encrypted output to file 'encryptedSecret.txt'.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.
Following envelope encryption best practices, you will now store the file encrypted with the encrypted data key and delete the plaintext key, avoiding getting it compromised.
Step 4 - Decrypt the encrypted secret text
If we want now to reverse the operation and decrypt the secret text stored in encryptedSecret.txt, it will be a 2 steps procedure.Remember that we don´t have the data key in plaintext to be used for decryption, we have removed it for security best practices.
We have the data key encrypted that was provided to us when calling the AWS KMS generate data key operation and that we stored as b64 decoded in file datakeyEncrypted.txt.
Therefore, the first step is to decrypt the data key with the appropriate Master Key (CMK) that was used to encrypt it. In this case we will use the command aws decrypt (see full reference in this part of documentation). This command will tell AWS KMS to revert the encryption made over the data key.
Note: 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.
The command will fail because when we generated the data key in plaintext and encrypted it with our CMK in the step 2, we used an encryption context.This encryption context was used in the encryption operation of the plaintext data key, this is: to produce the encrypted data key (the CiphertextBlob). Therefore we need to provide the encryption context to be able to decrypt correctly:
Great! As you can see, the output of the command has the data key in Plaintext. We had removed it and only stored it encrypted, but with AWS KMS and the appropriate CMK, we have it back.
We need now to 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.
Now that we have the data key in Plaintext and decoded from base64, let's decrypt:
Good job, we have the secret text 'Sample Secret Text to Encrypt' decrypted.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.
By completing this part of the workshop you now have a better understanding of what envelope ecnryption is, let's now see how it applies for AWS services working with AWS KMS.
Envelope encryption. Server side encryption
In AWS there are main two main procedures to protect your data at rest: Client Side Encryption (CSE) and Server Side Encryption (SSE).
For example in Amazon S3, you can encrypt your data before uploading it into the Amazon S3 Service (client side encryption) or encrypt once the data is there (server side encryption). More details in this link to the S3 documentation. A similar approach can be taken in other services like Amazon DynamoDB, see details here.
The envelope encryption mechanism just described in previous section is the mechanism behind the Server Side Encryption that takes place in the AWS services that use AWS KMS. There are very good descriptions on how AWS KMS is being used by different AWS services in this part of the AWS KMS documentation here.
For the workshop, let's see an example of attaching a disk to our working instance. We will encrypt it with AWS KMS and the CMK we have created importing our key material, its alias was 'ImportedCMK'.
We start by going into the AWS console. Navigate to Amazon EC2 service. Look in the left pane. Locate 'Elastic Block Store' and click on 'Volumes'.
<Figure-2>
Now in the upper area, you can click on 'Create Volume' to create a new Amazon EBS disk. Once in the volume creation screen, and for the workshorp, you can leave the defaults in most fields- Except for the following: Ensure you have selected the same 'Availability zone' as your EC2 instance is running on (It is easy to find out: you can look into the EC2 service, Instances area in the left pane, select your instance and locate the information 'Availability Zone' below). The disk can only be attached to instances in the same availability zone.
Ensure also that you have clicked the 'Encryption' checkbox. Then select the CMK you want to use from AWS KMS. Let's select the CMK that we have imported with our own key material, the alias was: ImportedCMK.
<Figure-3>
Create a tag for the volume, for example a key-pair like: Name: WorkshopEBS.Click on 'Create volume' at the right bottom of the screen. The volume will start being created and will be ready to be attached to the instance in a few seconds.
We have now a encrypted volume that can be attached to our instance.
In order to do so, navigating to EC2 service in the AWS console again, just go to the 'Volumes' in the left pane. Check Under 'Elastic Block Store' on the left are of the screen and select the volume you have created. Cick on the 'Actions' button and select 'Attach'. In the new window, select the instance we want it to be attached to.
Once the attachment process has finished, if you go back to the terminal connection to your instance, you can see the encrypted 100GiB disk is available for being mounted and used.
Behind the scenes, an envelope encryption process through AWS KMS has taken place:
Amazon EBS has requested AWS KMS to generate a data key under a CMK, 'ImportedCMK'. The encrypted data key is stored within the EBS volume metadata. When data needs to be stored (and therefore encrypted) in the EBS volume, Amazon EC2 ask AWS KMS to decrypt the encrypted data key that EBS has in the metadata. Amazon EC2 obtains the data key in Plaintext back from the operation with AWS KMS. Then, the data is encrypted with the Plaintext data key before being stored in EBS.
Furthermore, encryption context was used during the process to enforce the security and better traceability.The encryption context is used with the volume-id of the Amazon EBS volume in all the encryption and decryption operations.See more details in the following link to the Amazon EBS documentation.
Envelope encryption. Client side encryption
In the first topic of this section of the workshop (How Envelope Encryption works in practice) we have just seen an example of how AWS KMS can encrypt in client side by generating a data key, using an envelope encryption mechanism, to encrypt a secret text file with two tiers of protection.
While you can code all the primitives and commands to implement encryption on the client side, AWS has a SDK, the AWS Encryption SDK. This SDK uses envelope encryption and it is integrated with AWS KMS. It will implement most of the operations we have seen before as simple API calls. AWS KMS can become a Master Key provider for the AWS Encryption SDK, however you may use other Master Key provider with the SDK.
Aws Key Management Service Kms
I recommend to take a look at the AWS Encryption SDK. Also, some AWS services have specific encryption SDKs, like the one in Amazon DynamoDB: the 'DynamoDB Encryption Client', you can take a look in this link.
Encryption using AWS KMS with no Data Key
You can also use a CMK in AWS KMS to encrypt and decrypt a secret directly, without the generation of a Data Key and hence, without the envelope encryption process. Remember, AWS KMS is able to encrypt and decrypt up to 4 kilobytes (4096 bytes) of data. We can use the CLI or APIs.
In this example, we will use the CLI to encrypt a secret and decrypt using the CMK itself. Note: this encryption operation takes place in AWS KMS itself.When a data key is generated via the CMK, the encryption and decryption process with that data key happens outside AWS KMS.
Aws Kms Generate Data Key In Windows 10
Let's Create a new secret file.
We are going to encrypt it with a CMK and use an encryption context that will need to be provided in the decrypt operation.
Note we have called the CMK used to encrypt by its alias. The input file needs the 'fileb' prefix to be processed in binary, while the output is decoded from b64 to the new output file 'NewSecretsEncryptedFile.txt'
Aws Kms Generate Key
Take a look at the Encrypted file:
Great, It unreadable as is encrypted. Can´t read the original text. Now let's decrypt it.
Aws Cli Kms Generate Data Key
Wait, what is the problem?. At this point of the workshop, we should know that without the encryption context, the operation will not succeed. That was the problem. Let's try it again including the encryption context we stated during the encryption process:
If you now take a look at the file we have created with the previous command 'NewSecretsDecryptedFile.txt'. The secret text is now back unencrypted and ready for us.
Aws Kms Generate Data Key West
You have completed the second section of the workshop. In the next section we will work with a real-life Web App and will try to implement best practices. You can now navigate to the next section of the Workshop