AWS KMS (Key Management Service)
Detailed Content
AWS Key Management Service (KMS) makes it easy for you to create and manage cryptographic keys and control their use across a wide range of AWS services and in your applications. KMS is a secure and resilient service that uses FIPS 140-2 validated hardware security modules (HSMs) to protect your keys. It integrates with most other AWS services to provide encryption for your data at rest.
Core Concepts and Features
- Customer Master Keys (CMKs): The primary resources in KMS. CMKs are logical representations of a master key. They are used to encrypt and decrypt data keys. CMKs never leave KMS unencrypted.
- Symmetric CMKs: A single key is used for both encryption and decryption. Most common type.
- Asymmetric CMKs: A public key is used for encryption, and a private key for decryption (or vice versa for signing). Used for encryption or digital signatures.
- Data Keys: Encryption keys that you use to encrypt your data. KMS generates, encrypts, and decrypts data keys for you. Data keys are typically used for envelope encryption.
- Key Policies: The primary way to control access to your CMKs. Key policies are JSON documents that specify who can use the CMK and what cryptographic operations they can perform. Every CMK must have a key policy.
- IAM Policies: Used in conjunction with key policies to grant permissions to IAM users, groups, and roles to use CMKs. IAM policies define who can call KMS API operations.
- Key Rotation: KMS can automatically rotate the cryptographic material for AWS-managed CMKs and customer-managed CMKs (symmetric only) every year. This enhances security by regularly changing the underlying key material.
- Envelope Encryption: A common practice where you encrypt your data with a data key, and then encrypt the data key with a CMK. This allows you to encrypt large amounts of data efficiently while protecting the data key with a highly secure CMK.
- Key Usage: Defines whether a CMK can be used for
ENCRYPT_DECRYPT(symmetric and asymmetric) orSIGN_VERIFY(asymmetric only). - Auditability: All KMS API calls are logged by AWS CloudTrail, providing an auditable trail of key usage and management.
Types of Customer Master Keys (CMKs)
KMS supports several types of CMKs:
- AWS-managed CMKs: Created, managed, and used by an AWS service on your behalf (e.g., S3, EBS, RDS). You cannot directly manage these keys, but you can view their usage in CloudTrail.
- Customer-managed CMKs: Created, owned, and managed by you. You have full control over these keys, including defining key policies, enabling/disabling, scheduling deletion, and enabling key rotation. These are the most flexible type.
- AWS-owned CMKs: A collection of CMKs that AWS owns and manages for use in multiple AWS accounts. AWS services use AWS-owned CMKs to encrypt your data at rest by default. You cannot view or manage these keys.
- Custom Key Store CMKs: CMKs whose cryptographic material is stored in an AWS CloudHSM cluster or an external key manager outside of AWS. This provides an extra layer of control and compliance for your keys.
Use Cases
- Data Encryption at Rest: Encrypt data stored in various AWS services like S3, EBS, RDS, DynamoDB, Lambda environment variables, and more.
- Application-Level Encryption: Integrate KMS directly into your applications to encrypt sensitive data before storing it in databases or file systems.
- Secrets Management: Securely encrypt and decrypt secrets stored in AWS Secrets Manager or AWS Systems Manager Parameter Store.
- Digital Signatures: Use asymmetric CMKs to create and verify digital signatures for data integrity and authenticity.
- Compliance and Regulatory Requirements: Meet strict compliance standards (e.g., HIPAA, PCI DSS, GDPR) by using FIPS 140-2 validated KMS for key management.
- Envelope Encryption: Implement envelope encryption for large data sets, where KMS protects the data keys that encrypt your actual data.
Interview Questions
Conceptual Questions
- What is AWS KMS and what problem does it solve?
- AWS KMS is a managed service that makes it easy to create and manage cryptographic keys and control their use. It solves the problem of securely managing encryption keys, ensuring they are protected by FIPS 140-2 validated HSMs, and providing centralized control over cryptographic operations.
- Explain the difference between a Customer Master Key (CMK) and a Data Key in KMS.
- CMK (Customer Master Key): The primary resource in KMS, a logical representation of a master key. CMKs are used to encrypt and decrypt data keys. They never leave KMS unencrypted.
- Data Key: An encryption key that you use to encrypt your actual data. KMS generates, encrypts (with a CMK), and decrypts data keys for you. Data keys are typically used for envelope encryption.
- Describe the different types of CMKs available in KMS and when you would use each.
- AWS-managed CMKs: Managed by AWS for specific services (e.g., S3, EBS). Use when you want encryption but don't need direct control over the key.
- Customer-managed CMKs: Created and managed by you. Provides full control over key policies, rotation, and deletion. Use when you need fine-grained control over your encryption keys.
- AWS-owned CMKs: AWS owns and manages these for use across multiple accounts. You cannot manage them.
- Custom Key Store CMKs: Backed by CloudHSM or an external key manager. Use when you need to store key material in your own dedicated HSMs for compliance or extra control.
- What is Envelope Encryption and why is it a common practice with KMS?
- Envelope encryption is a practice where you encrypt your data with a data key, and then encrypt the data key with a CMK. It's common with KMS because CMKs are designed to be highly secure and never leave KMS, while data keys can be used outside KMS to encrypt large amounts of data efficiently. This combines the security of CMKs with the performance of data keys.
- How do Key Policies and IAM Policies work together to control access to CMKs?
- Key Policies: The primary access control mechanism for a CMK. They define who can use the CMK and what cryptographic operations they can perform. Every CMK must have a key policy.
- IAM Policies: Grant permissions to IAM users, groups, and roles to call KMS API operations. For an IAM principal to use a CMK, both the IAM policy and the CMK's key policy must allow the action.
Scenario-Based Questions
- Your application stores sensitive customer data in an S3 bucket. Your security policy requires that this data must be encrypted at rest, and you need to have full control over the encryption key's lifecycle, including who can use it and when. How would you configure encryption for this S3 bucket?
- I would configure Server-Side Encryption with AWS KMS (SSE-KMS) for the S3 bucket. Crucially, I would use a Customer-managed CMK that I create and manage in KMS. This allows me to define a key policy that specifies which IAM users/roles can use the CMK for encryption/decryption, enable automatic key rotation, and schedule its deletion. I would also enforce the use of this specific CMK via a bucket policy.
- You have an application running on an EC2 instance that needs to encrypt data before storing it in a database. The encryption key should be managed by KMS, but the actual encryption/decryption of the data should happen within the application for performance reasons. How would you implement this?
- I would use envelope encryption with KMS. The application would call KMS to generate a data key (a plaintext data key and its encrypted copy). The application would then use the plaintext data key to encrypt the data locally before storing it in the database. The encrypted data key would be stored alongside the encrypted data. When retrieving, the application would fetch the encrypted data key, send it to KMS for decryption (using a CMK), and then use the plaintext data key to decrypt the data locally. This leverages KMS for secure key management while performing bulk encryption/decryption efficiently within the application.
- Your organization has a strict compliance requirement that mandates that encryption keys must be stored in a dedicated hardware security module (HSM) that you own and control, not in a shared cloud service. How can you use KMS while meeting this requirement?
- I would use AWS KMS with a Custom Key Store backed by AWS CloudHSM. This allows me to create KMS CMKs whose cryptographic material is generated and stored in my dedicated AWS CloudHSM cluster. While I use the familiar KMS API for key management, the actual key material never leaves my CloudHSM, satisfying the compliance requirement for customer-owned and controlled HSMs.
- You need to ensure that all data stored in an Amazon RDS database is encrypted at rest. How would you enable this, and what happens to existing unencrypted databases?
- When creating a new Amazon RDS DB instance, I would simply select the option to enable encryption and choose an AWS-managed CMK or a customer-managed CMK. This encrypts the database, its automated backups, read replicas, and snapshots. For existing unencrypted databases, I cannot directly enable encryption. I would need to create a snapshot of the unencrypted database, then create a copy of that snapshot with encryption enabled, and finally restore a new DB instance from the encrypted snapshot. This new instance would be encrypted.
Coding/CLI Examples
Here are some common KMS operations using the AWS CLI and Python (Boto3).
AWS CLI Examples
-
Create a Customer-managed CMK (Symmetric):
bash aws kms create-key \ --description "CMK for application data encryption" \ --key-usage ENCRYPT_DECRYPT \ --key-spec SYMMETRIC_DEFAULT \ --tags TagKey=Name,TagValue=MyAppCMK -
Enable automatic key rotation for a CMK: ```bash KEY_ID="arn:aws:kms:us-east-1:123456789012:key/your-cmk-id" # Replace with your CMK ARN or ID
aws kms enable-key-rotation --key-id $KEY_ID ```
-
Generate a data key for envelope encryption: ```bash KEY_ID="arn:aws:kms:us-east-1:123456789012:key/your-cmk-id" # Replace with your CMK ARN or ID
aws kms generate-data-key \ --key-id $KEY_ID \ --key-spec AES_256 \ --query '[Plaintext,CiphertextBlob]' --output text ```
-
Encrypt data using a CMK: ```bash KEY_ID="arn:aws:kms:us-east-1:123456789012:key/your-cmk-id" # Replace with your CMK ARN or ID
Create a dummy plaintext file
echo "This is my secret data." > plaintext.txt
aws kms encrypt \ --key-id $KEY_ID \ --plaintext fileb://plaintext.txt \ --query CiphertextBlob --output text > ciphertext.base64
Decode the base64 output to get the binary ciphertext
base64 --decode ciphertext.base64 > ciphertext.bin ```
-
Decrypt data using a CMK: ```bash KEY_ID="arn:aws:kms:us-east-1:123456789012:key/your-cmk-id" # Replace with your CMK ARN or ID
aws kms decrypt \ --ciphertext-blob fileb://ciphertext.bin \ --query Plaintext --output text > decrypted_plaintext.txt ```
Python (Boto3) Examples
First, ensure you have Boto3 installed (pip install boto3) and your AWS credentials configured.
-
Create a Customer-managed CMK (Symmetric): ```python import boto3
kms_client = boto3.client('kms')
key_alias = "alias/MyBoto3AppCMK"
try: response = kms_client.create_key( Description='CMK for Boto3 application data', KeyUsage='ENCRYPT_DECRYPT', KeySpec='SYMMETRIC_DEFAULT', Tags=[ {'TagKey': 'Name', 'TagValue': 'MyBoto3AppCMK'} ] ) key_id = response['KeyMetadata']['KeyId'] key_arn = response['KeyMetadata']['Arn'] print(f"Created CMK: {key_arn}")
# Create an alias for easier reference kms_client.create_alias(AliasName=key_alias, TargetKeyId=key_id) print(f"Created alias {key_alias} for CMK {key_id}")except Exception as e: print(f"Error creating CMK: {e}") ```
-
Generate a data key and encrypt/decrypt data using envelope encryption: ```python import boto3 import base64
kms_client = boto3.client('kms')
cmk_id = "alias/MyBoto3AppCMK" # REPLACE with your CMK ID or ARN plaintext_data = b"This is my super secret data that needs to be encrypted."
try: # 1. Generate a data key generate_key_response = kms_client.generate_data_key( KeyId=cmk_id, KeySpec='AES_256' # Generates a 256-bit AES data key ) plaintext_data_key = generate_key_response['Plaintext'] encrypted_data_key = generate_key_response['CiphertextBlob']
print("Data key generated.") # 2. Encrypt data locally with the plaintext data key # (This part would typically use a cryptographic library like cryptography) # For demonstration, we'll just simulate encryption encrypted_data = plaintext_data # In a real scenario, this would be encrypted print("Data encrypted locally (simulated).") # Store encrypted_data and encrypted_data_key # 3. Decrypt the encrypted data key using KMS decrypt_key_response = kms_client.decrypt(CiphertextBlob=encrypted_data_key) decrypted_data_key = decrypt_key_response['Plaintext'] print("Encrypted data key decrypted by KMS.") # 4. Decrypt data locally with the decrypted data key # (This part would typically use a cryptographic library like cryptography) decrypted_data = encrypted_data # In a real scenario, this would be decrypted print(f"Data decrypted locally (simulated): {decrypted_data.decode()}")except Exception as e: print(f"Error with envelope encryption: {e}") ```