AWS Database Blog

How to encrypt Amazon Aurora using AWS KMS and your own KMS key

When selecting a relational database engine, customers look at many different aspects, including management, performance, reliability, automation, and more recently, the ability to natively encrypt data at rest. Amazon Aurora provides a highly available, optimal, and scalable relational database engine that supports both MySQL and PostgreSQL. Amazon Aurora also supports native encryption of data at rest and uses AWS Key Management Service (AWS KMS) to store and manage the keys used for this encryption.

You can use AWS KMS to create, store, and manage your encryption keys. It’s backed by a hardware security module (HSM), which gives you confidence that your keys are stored securely.

AWS KMS controls and policies have been validated and certified by the following compliance regimes:

A feature of AWS KMS is to use customer managed keys, or KMS keys. By using a KMS key in AWS KMS, you gain the ability to rotate the key according to your own policies, delete the key, and control access to the key via KMS policies and IAM policies. You can choose to have AWS KMS generate a managed key on your behalf, or you can import your own key material using the Import Key feature. By importing your own key material, you can keep a copy under your control and re-import it in the future as needed.

It is important to note that when you import your own key material, you become responsible for the availability and durability of your key. You are allowed only one key per KMS key, and ciphertext is not portable between KMS keys. For more information, see Considerations for Imported Key Material in the AWS KMS Developer Guide.

Solution diagram and explanation

The following diagram illustrates the solution in this post:

At a high level, the Amazon Aurora database (1) uses a customer managed key (2) stored in AWS KMS (3) to encrypt the data (4) at rest in the database (1).

In more detail, Aurora gets a unique 256-bit data encryption key (DEK) from AWS KMS for each Aurora database instance. That DEK is provisioned into memory on Aurora hosts while the database instance is running. A copy of the DEK that is encrypted under the KMS key is stored by Amazon RDS so that it can launch future snapshots of the database.

It’s important to note that although multiple keys are stored in memory, none of these keys are written to disk without being encrypted first. The ability to decrypt any keys and to decrypt Aurora snapshots at rest always requires an authenticated call to AWS KMS. This is how we help prevent unauthorized access to encrypted data at rest.

Solution overview

The first step in this process is to generate a new KMS key with your imported key material. The overall steps are as follows:

  1. Create a KMS key container in AWS KMS with key origin as external.
  2. Download the public wrapping key.
  3. Encrypt the key material with this wrapping key.
  4. Import encrypted key material into the KMS key container in AWS KMS.

Next, you configure Amazon Aurora to use the imported KMS key to encrypt the data at rest in the database.

Although I cover AWS KMS policies briefly, this post does not focus on them. For more information about AWS KMS key policies, see Using Key Policies in AWS KMS in the AWS KMS Developer Guide.

Creating a new KMS key

First, create a new KMS key in AWS KMS:

  1. Sign in to the AWS Management Console and open the IAM console.
  2. In the left navigation pane, choose Encryption keys.
  3. You now need to choose which AWS Region to create the new key in. This Region must be the same as the one in which you will create the Amazon Aurora database instance. This example uses the EU (London) Region.
  4. Choose Create key.
  5. Choose a relevant alias and description for your key. Under Advanced Options, choose External for Key Material Origin. Select the check box and choose Next Step.
  6. Select any key-value pair tags that you want to use for your key. Tags help you identify this key. They can be used to identify the cost center, project code, or owner of the key. Then choose Next Step.
  7. Select the user or role with which you want to administer the key. Administrators cannot use the key to perform encrypt or decrypt operations, but they can modify the key policy to give themselves these permissions. In this example, choose the Admin role, and give the role the ability to delete the key. Then choose Next Step.
  8. Select the user or role to which you want to give key usage permissions. These permissions provide the ability to perform encrypt or decrypt operations, but not manage the key. This example uses AWSServiceRoleForRDS. This role is predefined by AWS and is the service role in which Amazon RDS runs. When you add this role as a key user, it allows the Amazon Aurora database to use the KMS key. Then choose Next Step.
  9. Finally, get a summary of the key policy shown as a JSON policy. It is always recommended that you review this to ensure that you are granting the appropriate roles and users to administer and use the key.

You have now created a KMS key with relevant permissions into which you can import your key material.

Importing key material

The new KMS key is ready to receive your imported key material. In this example, you use OpenSSL to generate a 256-bit symmetric key, and then encrypt this key for import into AWS KMS. For information and instructions on how to download and install OpenSSL, see the OpenSSL website. AWS recommends that you use a more secure method of generating and storing your key material, such as an HSM or other key management system.

AWS KMS provides three different encryption schemes that you can use:

  • RSAES_OAEP_SHA_256 – RSA encryption with OAEP and SHA-256 hash
  • RSAES_OAEP_SHA_1 – RSA encryption with OAEP and SHA-1 hash
  • RSAES_PKCS1_V1_5 – RSA encryption with PKCS#1 v1.5

Because this example is using OpenSSL, I will use RSAES_OAEP_SHA_1. AWS recommends that you use RSAES_OAEP_SHA_256 if it is supported by the HSM or key management system that is being used.

AWS KMS creates a wrapping key and an import token to use for importing the key material. The wrapping key is the public key that is used to encrypt the raw key material before upload. The import token contains metadata to ensure that the material is imported correctly.

For more information, see Importing Key Material in AWS KMS.

  1. This example uses RSAES_OAEP_SHA_1. Choose it in the drop-down list, and then choose Download wrapping key and import token.
  2. This step downloads a file named ImportParameters.zip. Extract the README, ImportToken, and WrappingKey
  3. Use the rand function in OpenSSL as follows to generate a pseudo-random 32-byte, or 256-bit, string and output it to a file named bin. For more information, see The OpenSSL Documentation.
    $ openssl rand -out PlaintextKeyMaterial.bin 32
  4. Next, take the bin file and encrypt it using the WrappingKey downloaded from the console. To do this, use the rsautl function in OpenSSL with the following command. Replace the value of -in with the key material that was generated in step 3. Replace the value of -inkey with the wrapping key extracted in step 2. For more information, see the OpenSSL documentation.
    $ openssl rsautl -encrypt \
                     -in PlaintextKeyMaterial.bin \
                     -oaep \
                     -inkey WrappingKey.bin \
                     -keyform DER \
                     -pubin \
                     -out EncryptedKeyMaterial.bin
  5. Now that you have the key material that is encrypted with the public key, return to the console. Select the I am ready to upload my exported key material check box, and choose Next.
  6. Next, choose the Encrypted key material file that was generated with the OpenSSL rsautl function, and the Import token that was downloaded from the console. Also, choose the option to not have this key automatically expire. Then choose Finish.

You have now completed the import process, and you have created a new KMS key that contains the encrypted imported key material.

Encrypting an Aurora database with the imported KMS key

You will now create an Amazon Aurora MySQL cluster, and use the KMS key to encrypt the data at rest.

For this post, you will use the smallest instance class, db.t2.small, which has 1 vCPU and 2 GiB of RAM. Other instance classes are available with different vCPU and RAM allocations.

  1. On the AWS Management Console, choose Relational Database Service or RDS.
  2. I always double check that I am in the same Region, (EU) London, as the KMS key I created. Choose Get started now.
  3. Choose Amazon Aurora as the engine and choose the MySQL 5.6-compatible edition. Then choose Next.
  4. For the DB details, choose the smallest instance class, t2.small. You can also select Multi-AZ deployment if you need the database to be highly available. For more information about instance classes, see DB Instance Class. For information about Multi-AZ deployments, see High Availability (Multi-AZ).
  5. Scroll down to the instance settings. Here you specify your DB instance identifier, a user name, and a password for master access to the database. Then choose Next.
  6. You now need to fill out your networking configuration. Use the default virtual private cloud (VPC) and create a new subnet group. Don’t make your DB accessible to the public, and don’t specify any preference for the Availability Zone. Choose Create new VPC security group. For more information about networking and VPCs for Amazon Aurora, see Working with an Amazon RDS DB Instance in a VPC.
  7. Scrolling down, you can now specify your cluster identifier, database name, and port. Optionally, you can also set the parameter group for the DB and the cluster. Parameter groups control the configuration settings that are applied to the DB instance and cluster. For more information, see Working with DB Parameter Groups.
  8. Scrolling down, you can now specify the encryption key that you want to use. Here you can enable encryption and choose the KMS key that you created earlier. To verify, you can check that the KMS key ID matches what was created earlier. For failover priority, leave the preference at default. For more information, see Fault Tolerance for an Aurora DB Cluster.
  9. Scroll down, and choose the backup retention that you want, and whether you want enhanced or standard monitoring. For more information, see Enhanced Monitoring in the Amazon RDS documentation.
  10. Finally, choose Launch DB instance.

You have now created a new, highly available Amazon Aurora cluster. You have specified the KMS key that you created earlier to be used to encrypt data at rest.

To verify this, follow these steps:

  1. Go back to the Amazon RDS console and choose Instances in the left navigation pane.
  2. Wait until the instance status is available. if it is not yet available, wait for a few minutes and refresh the page. Then choose one of the database instances that you created.
  3. Scroll down to the Details On the lower-right side, you can see that the database is encrypted, and which key is being used for this encryption.

Conclusion

In this post, I walked through creating a new KMS key with imported material, and then used it to encrypt an Amazon Aurora database.

If you have any questions, comments, or suggestions, please leave a comment below. You can also visit the AWS Forums for Amazon RDS and AWS KMS.

If you want more information about cryptography on AWS, we have documentation available on Cryptography Basics, and a whitepaper on AWS Key Management Service Cryptographic Details.


About the Author

Andrew Robinson is a solutions architect at Amazon Web Services. He works with the AWS customers to provide guidance and technical assistance on database projects, helping them improve the value of their solutions when using AWS.