AWS-QwikLabs : KMS (Key Management Service)
- Data keys are encryption keys that we can use to encrypt data. To create a data key, call the GenerateDataKey operation and KMS uses the CMK that we specify. The CMK creates a plaintext data key and an encrypted data key.
- Customer master key (CMK) is the key at the top of key hierarchy.
AWS KMS uses the customer master key to decrypt the encrypted data key stored along with the data. It returns the plaintext key which is then used to decrypt the data again this plaintext key is removed from the memory. - Envelope encryption: when we encrypt our data, our data is protected, but we have to protect our encryption key by encrypting it. Envelope encryption is the practice of encrypting plaintext data with a data key, and then encrypting the data key under another key.
AWS KMS cannot use a data key to encrypt data. But we can use the data key outside of AWS KMS (OpenSSL or a cryptographic library like the AWS Encryption SDK). After using the plaintext data key to encrypt data, we should remove it from memory as soon as possible. We can safely store the encrypted data key with the encrypted data so it is available to decrypt the data.
In this post, we'll create an Encryption Key and encrypt the data stored in S3 bucket. Then, we will make a Get request with presigned URL for the sse-kms encrypted object using Postman. We'll also monitor the CloudTrail log for the key usage.
This post is partially based on Introduction to Amazon CloudFront
Let's create our KMS master key.
Here is the key policy:
{ "Id": "key-consolepolicy-3", "Version": "2012-10-17", "Statement": [ { "Sid": "Enable IAM User Permissions", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::526262051452:root" }, "Action": "kms:*", "Resource": "*" }, { "Sid": "Allow access for Key Administrators", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::526262051452:user/K" }, "Action": [ "kms:Create*", "kms:Describe*", "kms:Enable*", "kms:List*", "kms:Put*", "kms:Update*", "kms:Revoke*", "kms:Disable*", "kms:Get*", "kms:Delete*", "kms:TagResource", "kms:UntagResource", "kms:ScheduleKeyDeletion", "kms:CancelKeyDeletion" ], "Resource": "*" }, { "Sid": "Allow use of the key", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::526262051452:user/K" }, "Action": [ "kms:Encrypt", "kms:Decrypt", "kms:ReEncrypt*", "kms:GenerateDataKey*", "kms:DescribeKey" ], "Resource": "*" }, { "Sid": "Allow attachment of persistent resources", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::526262051452:user/K" }, "Action": [ "kms:CreateGrant", "kms:ListGrants", "kms:RevokeGrant" ], "Resource": "*", "Condition": { "Bool": { "kms:GrantIsForAWSResource": "true" } } } ] }
Click "Finish".
Actually, as we can see it's a "Customer managed keys":
We can get the policy using the following command as well:
$ aws kms get-key-policy --key-id fb17f3e0-0a0e-4fdb-889f-5c033a8bc664 --policy-name default --output text > policy.txt
We want to upload a file from local machine to s3 with kms encryption using the following command:
aws s3 cp /filepath s3://mybucket/filename --sse aws:kms --sse-kms-key-id <key id>
Let's create a bucket first, and then upload a file with the kms-key-id. To get the id:
$ aws kms list-aliases { "Aliases": [ ... { "AliasName": "alias/myFirstKey", "AliasArn": "arn:aws:kms:us-east-1:526262051452:alias/myFirstKey", "TargetKeyId": "da0f41cc-b71c-484f-977f-f4edac09859a" } ] }
Let's create the bucket and upload our file with encryption:
$ aws s3 mb s3://kms-bogo-test $ aws s3 cp ./eiffel.png s3://kms-bogo-test/eiffel.png --sse aws:kms --sse-kms-key-id da0f41cc-b71c-484f-977f-f4edac09859a upload: ./eiffel.png to s3://kms-bogo-test/eiffel.png
We used the option --sse that specifies server-side encryption of the object in S3. Valid values are AES256 and aws:kms.
Also, there is another option --sse-kms-key-id we used in the command. Note that we should only provide this parameter if KMS key ID is different the default S3 master KMS key.
After making the image public, we get the following error when we access it from a browser:
<Error> <Code>InvalidArgument</Code> <Message> Requests specifying Server Side Encryption with AWS KMS managed keys require AWS Signature Version 4. </Message> <ArgumentName>Authorization</ArgumentName> <ArgumentValue>null</ArgumentValue> <RequestId>FCC533C8E70958C6</RequestId> <HostId> X3Jq8qbLw9Qf15zPgLbrwcYtDRWmcGCkE9SKA64EONDl3WWSx3iM23ytoRS4QAqKYizJBf4HLZM= </HostId> </Error>
The following will generate a URL that will expire in 3600 seconds (default):
$ aws s3 presign s3://kms-bogo-test/eiffel.png https://kms-bogo-test.s3.amazonaws.com/eiffel.png?AWSAccessKeyId=AKIAIY6RID2W2C5I3P5Q&Signature=v3gTX6YiTZ4aWYDtOyfwaJWlxSc%3D&Expires=1547347373 https://kms-bogo-test.s3.amazonaws.com/eiffel.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIY6RID2W2C5I3P5Q%2F20190113%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20190113T051556Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=0fd284192f221c26b57e21636995a57283f6877c8165cd1e1085b5ab7ab44f40
Check presign: "Generate a pre-signed URL for an Amazon S3 object. This allows anyone who receives the pre-signed URL to retrieve the S3 object with an HTTP GET request. For sigv4 requests the region needs to be configured explicitly."
We need to make a REST API call.
Ref : How to Use the REST API to Encrypt S3 Objects by Using AWS KMS
In this section, we'll use the URL we got from aws s3 presign
in the previous section. To make a REST API call, we use POSTMAN. Here is the outcome when we make a GET request :
Click "Create":
Check the logs on S3:
Here are the processes how the SSE-KMS encryption works:
A user (or a client) wants to upload a text that has sensitive information and store it using SSE (Server Side Encryption) KMS.
When the request made to S3, S3 will handle the KMS service for the user. S3 realizes it needs to invoke KMS services. So, it calls upon KMS to generate data key for the user, and it send a request over to KMS.
-
At this point, the KMS uses the specified CMK (Customer Master Key) to generate two keys. The first key is a plain data text key, and the 2nd key is the same key but encrypted version of that key.
Both keys are then sent back to S3, and S3 sees two keys (plain data text key and encrypted data key). Now S3 has all keys to process encryption.
S3 takes the object uploaded by the user and combine with the plain data text key to perform encryption. S3 now has the encrypted version of the document alongside with the encrypted data key. The plain data text key will be deleted from the memory.
SSE-KMS decryption:
A user (or a client) wants to get an SSE-KMS encrypted text.
When the request made to S3, S3 knows the requested object has an associated encrypted data key. So, S3 sends the encrypted data key over to KMS.
-
Then, KMS uses the CMK (Customer Master Key) and the encrypted data key to generate plain version of that key.
S3 takes the plain text data key to decrypt the object.
S3 returns the plain document to the client.
AWS (Amazon Web Services)
- AWS : EKS (Elastic Container Service for Kubernetes)
- AWS : Creating a snapshot (cloning an image)
- AWS : Attaching Amazon EBS volume to an instance
- AWS : Adding swap space to an attached volume via mkswap and swapon
- AWS : Creating an EC2 instance and attaching Amazon EBS volume to the instance using Python boto module with User data
- AWS : Creating an instance to a new region by copying an AMI
- AWS : S3 (Simple Storage Service) 1
- AWS : S3 (Simple Storage Service) 2 - Creating and Deleting a Bucket
- AWS : S3 (Simple Storage Service) 3 - Bucket Versioning
- AWS : S3 (Simple Storage Service) 4 - Uploading a large file
- AWS : S3 (Simple Storage Service) 5 - Uploading folders/files recursively
- AWS : S3 (Simple Storage Service) 6 - Bucket Policy for File/Folder View/Download
- AWS : S3 (Simple Storage Service) 7 - How to Copy or Move Objects from one region to another
- AWS : S3 (Simple Storage Service) 8 - Archiving S3 Data to Glacier
- AWS : Creating a CloudFront distribution with an Amazon S3 origin
- AWS : Creating VPC with CloudFormation
- AWS : WAF (Web Application Firewall) with preconfigured CloudFormation template and Web ACL for CloudFront distribution
- AWS : CloudWatch & Logs with Lambda Function / S3
- AWS : Lambda Serverless Computing with EC2, CloudWatch Alarm, SNS
- AWS : Lambda and SNS - cross account
- AWS : CLI (Command Line Interface)
- AWS : CLI (ECS with ALB & autoscaling)
- AWS : ECS with cloudformation and json task definition
- AWS Application Load Balancer (ALB) and ECS with Flask app
- AWS : Load Balancing with HAProxy (High Availability Proxy)
- AWS : VirtualBox on EC2
- AWS : NTP setup on EC2
- AWS: jq with AWS
- AWS & OpenSSL : Creating / Installing a Server SSL Certificate
- AWS : OpenVPN Access Server 2 Install
- AWS : VPC (Virtual Private Cloud) 1 - netmask, subnets, default gateway, and CIDR
- AWS : VPC (Virtual Private Cloud) 2 - VPC Wizard
- AWS : VPC (Virtual Private Cloud) 3 - VPC Wizard with NAT
- DevOps / Sys Admin Q & A (VI) - AWS VPC setup (public/private subnets with NAT)
- AWS - OpenVPN Protocols : PPTP, L2TP/IPsec, and OpenVPN
- AWS : Autoscaling group (ASG)
- AWS : Setting up Autoscaling Alarms and Notifications via CLI and Cloudformation
- AWS : Adding a SSH User Account on Linux Instance
- AWS : Windows Servers - Remote Desktop Connections using RDP
- AWS : Scheduled stopping and starting an instance - python & cron
- AWS : Detecting stopped instance and sending an alert email using Mandrill smtp
- AWS : Elastic Beanstalk with NodeJS
- AWS : Elastic Beanstalk Inplace/Rolling Blue/Green Deploy
- AWS : Identity and Access Management (IAM) Roles for Amazon EC2
- AWS : Identity and Access Management (IAM) Policies, sts AssumeRole, and delegate access across AWS accounts
- AWS : Identity and Access Management (IAM) sts assume role via aws cli2
- AWS : Creating IAM Roles and associating them with EC2 Instances in CloudFormation
- AWS Identity and Access Management (IAM) Roles, SSO(Single Sign On), SAML(Security Assertion Markup Language), IdP(identity provider), STS(Security Token Service), and ADFS(Active Directory Federation Services)
- AWS : Amazon Route 53
- AWS : Amazon Route 53 - DNS (Domain Name Server) setup
- AWS : Amazon Route 53 - subdomain setup and virtual host on Nginx
- AWS Amazon Route 53 : Private Hosted Zone
- AWS : SNS (Simple Notification Service) example with ELB and CloudWatch
- AWS : Lambda with AWS CloudTrail
- AWS : SQS (Simple Queue Service) with NodeJS and AWS SDK
- AWS : Redshift data warehouse
- AWS : CloudFormation
- AWS : CloudFormation Bootstrap UserData/Metadata
- AWS : CloudFormation - Creating an ASG with rolling update
- AWS : Cloudformation Cross-stack reference
- AWS : OpsWorks
- AWS : Network Load Balancer (NLB) with Autoscaling group (ASG)
- AWS CodeDeploy : Deploy an Application from GitHub
- AWS EC2 Container Service (ECS)
- AWS EC2 Container Service (ECS) II
- AWS Hello World Lambda Function
- AWS Lambda Function Q & A
- AWS Node.js Lambda Function & API Gateway
- AWS API Gateway endpoint invoking Lambda function
- AWS API Gateway invoking Lambda function with Terraform
- AWS API Gateway invoking Lambda function with Terraform - Lambda Container
- Amazon Kinesis Streams
- AWS: Kinesis Data Firehose with Lambda and ElasticSearch
- Amazon DynamoDB
- Amazon DynamoDB with Lambda and CloudWatch
- Loading DynamoDB stream to AWS Elasticsearch service with Lambda
- Amazon ML (Machine Learning)
- Simple Systems Manager (SSM)
- AWS : RDS Connecting to a DB Instance Running the SQL Server Database Engine
- AWS : RDS Importing and Exporting SQL Server Data
- AWS : RDS PostgreSQL & pgAdmin III
- AWS : RDS PostgreSQL 2 - Creating/Deleting a Table
- AWS : MySQL Replication : Master-slave
- AWS : MySQL backup & restore
- AWS RDS : Cross-Region Read Replicas for MySQL and Snapshots for PostgreSQL
- AWS : Restoring Postgres on EC2 instance from S3 backup
- AWS : Q & A
- AWS : Security
- AWS : Security groups vs. network ACLs
- AWS : Scaling-Up
- AWS : Networking
- AWS : Single Sign-on (SSO) with Okta
- AWS : JIT (Just-in-Time) with Okta
Ph.D. / Golden Gate Ave, San Francisco / Seoul National Univ / Carnegie Mellon / UC Berkeley / DevOps / Deep Learning / Visualization