AWS S3 (Amazon Simple Storage Service) offers several methods for encrypting objects. These encryption methods safeguard data at rest, ensuring protection even if physical hardware is compromised. Server-side encryption (SSE) is used, where S3 encrypts objects before saving them on disks. You can also enforce encryption in transit when communicating with HTTP endpoints of the S3 buckets by using Secure Socket Layer/Transport Layer Security (SSL/TLS) or client-side encryption. In general, there are two main types of encryption available for S3 objects: Server-side encryption and Client-side encryption
Server-Side Encryption (SSE)
This method encrypts your objects before saving them on disks in AWS data centers and then decrypts the objects when you download them.
There are four types of server-side encryption (for December 2023):
Server-side encryption with Amazon S3 managed keys (SSE-S3): Uses keys managed by AWS S3 and is the default encryption configuration for every bucket in Amazon S3. Each object is encrypted with a unique key and as an additional safeguard, it encrypts the key itself with a master key that it regularly rotates. SSE-S3 uses one of the strongest block ciphers available, 256-bit Advanced Encryption Standard (AES-256), to encrypt the data. There is no additional cost or performance impact. To configure server-side encryption by using the object creation REST APIs, you must provide the
x-amz-server-side-encryption
request header. For information about the REST APIs, see Using the REST API.💡To use a different type of encryption, you can either specify the type of server-side encryption to use in your S3PUT
requests, or you can set the default encryption configuration in the destination bucket. Learn more >>Server-side encryption with AWS Key Management Service Keys (SSE-KMS): Uses AWS Key Management Service (KMS) keys. This allows you to use customer master keys (CMKs) to have more control over who can use the encryption keys to access your data. Object is encrypted server-side and for REST API request must set header
x-amz-server-side-encryption: aws:kms
Learn more>>💡The KMS keys that you create are customer managed keys. AWS services that use KMS keys to encrypt your service resources often create keys for you. KMS keys that AWS services create in your AWS account are AWS managed keys. KMS keys that AWS services create in a service account are AWS owned keys. Learn more >>It also provides an audit trail that shows when and by whom the key was used by using AWS CloudTrail service.
Dual-layer server-side encryption with AWS KMS keys (DSSE-KMS): Using dual-layer server-side encryption with AWS Key Management Service (AWS KMS) keys (DSSE-KMS) applies two layers of encryption to objects when they are uploaded to Amazon S3. Each layer of encryption uses a separate cryptographic implementation library with individual data encryption keys. DSSE-KMS helps you more easily fulfill compliance standards that require you to apply multilayer encryption to your data and have full control of your encryption keys. Learn more >>
To set the encryption via REST API must set the
x-amz-server-side-encryption: aws:kms:dsse
header.When you use DSSE-KMS with an Amazon S3 bucket, the AWS KMS keys must be in the same Region as the bucket. Also, when DSSE-KMS is requested for the object, the S3 checksum that's part of the object's metadata is stored in encrypted form. For more information about checksums, see Checking object integrity.
There are additional charges for using DSSE-KMS and AWS KMS keys. For more information about DSSE-KMS pricing, see AWS KMS key concepts in the AWS Key Management Service Developer Guide and AWS KMS pricing.
Server-side encryption with customer-provided keys (SSE-C):
Allows you to manage your own encryption keys. Here, AWS S3 manages encryption and decryption of your objects but you manage and provide the encryption key by using the following headers:
Name | Description |
x-amz-server-side-encryption-customer-algorithm | Use this header to specify the encryption algorithm. The header value must be AES256 . |
x-amz-server-side-encryption-customer-key | Use this header to provide the 256-bit, base64-encoded encryption key for Amazon S3 to use to encrypt or decrypt your data. |
x-amz-server-side-encryption-customer-key-MD5 | Use this header to provide the base64-encoded 128-bit MD5 digest of the encryption key according to RFC 1321. Amazon S3 uses this header for a message integrity check to ensure that the encryption key was transmitted without error. |
Client-Side Encryption
In this method, you encrypt data on the client side before uploading it to S3 to help ensure its security in transit and at rest.
You also manage the encryption process, the encryption keys, and related tools. Amazon S3 receives your objects already encrypted; Amazon S3 does not play a role in encrypting or decrypting your objects. You can use both the Amazon S3 Encryption Client and server-side encryption to encrypt your data. When you send encrypted objects to Amazon S3, Amazon S3 doesn't recognize the objects as being encrypted, it only detects typical objects. There are two ways to handle client-side encryption:
Using a client library such as the Amazon S3 Encryption Client: The Amazon S3 Encryption Client works as an intermediary between you and Amazon S3. After you instantiate the Amazon S3 Encryption Client, your objects are automatically encrypted and decrypted as part of your Amazon S3
PutObject
andGetObject
requests. Your objects are all encrypted with a unique data key. The Amazon S3 Encryption Client does not use or interact with bucket keys, even if you specify a KMS key as your wrapping key. For more information, see What is the Amazon S3 Encryption Client?Manually encrypting before uploading: You can also encrypt your data using your own encryption mechanism before uploading it to S3.
Each method has its own use cases, benefits, and considerations. Server-side encryption is simpler to implement as AWS manages most aspects of the encryption process, whereas client-side encryption gives you more control over the encryption keys and procedures. The choice between these methods depends on your specific security requirements and operational preferences.
Tutorial: Check default encryption type for an object uploaded to S3 bucket
This tutorial checks the default encryption type for an object Server-Side Encryption with Amazon S3 Managed Keys (SSE-S3) and assumes that you have the AWS CLI installed and configured with the necessary permissions.
Step 1: Create an S3 Bucket
If you don’t already have an S3 bucket, create one:
Open your terminal or command prompt.
Run the following command to create a new bucket (replace
my-s3-bucket
with a unique bucket name):aws s3 mb s3://my-s3-bucket
Step 2: Upload an Object with SSE-S3 Encryption
Upload a file to your S3 bucket with SSE-S3 encryption:
Create a test file on your local machine, for example,
testfile.txt
.Run the following command to upload the file with SSE-S3 encryption:
aws s3 cp testfile.txt s3://my-s3-bucket/testfile.txt --sse AES256
To specify SSE-S3 when you upload an object by using the AWS CLI, use the following example:
aws s3api put-object --bucket DOC-EXAMPLE-BUCKET1 --key object-key-name --server-side-encryption AES256 --body file path
Step 3: Verify the Encryption Type of the Uploaded Object
After uploading the file, check the default encryption type:
Run the following command to retrieve the object's metadata:
aws s3api head-object --bucket my-s3-bucket --key testfile.txt
In the output, look for the
ServerSideEncryption
parameter. It should showAES256
, indicating SSE-S3 encryption.
Step 4: Downloading the Object
You can download the object to verify that it can be accessed normally:
Run the following command to download the file:
aws s3 cp s3://my-s3-bucket/testfile.txt downloadedfile.txt
Check
downloadedfile.txt
on your local machine to ensure it matches the original file.
Additional Notes:
Bucket-Level Encryption: Optionally, you can set the default encryption on the S3 bucket to automatically encrypt all objects uploaded to it with SSE-S3. Use this command:
aws s3api put-bucket-encryption --bucket my-s3-bucket --server-side-encryption-configuration '{"Rules":[{"ApplyServerSideEncryptionByDefault":{"SSEAlgorithm":"AES256"}}]}'
❗Please note that bucket-level encryption can be skipped as starting January 5, 2023, all new object uploads to Amazon S3 are automatically encrypted at no additional cost and with no impact on performance. Nonetheless as bucket level permissions are evaluated before default S3 encryption, you can "force encryption" and refuse any API calls to PUT an S3 object without encryption headers. Learn more >>Permissions: Ensure that your AWS IAM user has the necessary permissions to perform these actions. The required permissions include
s3:PutObject
,s3:GetObject
, ands3:PutBucketEncryption
.Region Selection: When creating a bucket, be aware that S3 bucket names are globally unique. If you get an error regarding the bucket name, try a different name or specify a region with
--region <region-name>
in themb
command.Security Best Practices: Always follow AWS security best practices, especially when handling sensitive data. This includes using IAM roles and policies to restrict access appropriately.
By following these steps, you can successfully test and verify the use of SSE-S3 for object encryption in AWS S3.
Tutorial: Change default encryption setting for the existing S3 bucket to SSE-KMS
To change the encryption setting of your S3 bucket (my-s3-bucket
) from SSE-S3 (Server-Side Encryption with Amazon S3 managed keys) to SSE-KMS (Server-Side Encryption with AWS Key Management Service), you need to perform the following steps. This process involves using a customer master key (CMK) in AWS KMS for encryption.
Step 1: Create or Identify Your AWS KMS Key
First, you need a KMS key to use for encryption. You can either create a new KMS key or use an existing one. If you already have a KMS key, skip to Step 2.
To create a new KMS key, use the AWS Management Console. You can keep settings as default:
Once created, note the key ID or the Amazon Resource Name (ARN) of the KMS key.
Step 2: Set the Bucket Encryption to Use SSE-KMS
After you have your KMS key ID or ARN, you can update the bucket encryption settings:
Open your terminal or command prompt.
Use the following AWS CLI command to update the bucket encryption settings. Replace
<kms-key-id>
with your KMS key ID or ARN:aws s3api put-bucket-encryption --bucket my-s3-bucket --server-side-encryption-configuration '{"Rules":[{"ApplyServerSideEncryptionByDefault":{"SSEAlgorithm":"aws:kms","KMSMasterKeyID":"<kms-key-id>"}}]}'
Step 3: Verify the Encryption Setting of the Bucket
To confirm that the bucket encryption setting is updated:
Run the following command:
aws s3api get-bucket-encryption --bucket my-s3-bucket
The output should show the encryption configuration using
aws:kms
and your specified KMS key ID.
Additional Information
Permissions: Make sure that your IAM user has the necessary permissions to manage S3 bucket encryption settings and to use the specified KMS key.
Existing Objects: Changing the bucket encryption settings does not retroactively change the encryption of existing objects in the bucket. New objects uploaded to the bucket will use the new encryption settings.
Costs: Be aware that using KMS keys may incur additional costs compared to using SSE-S3.
Security: As with any encryption key management, handle your KMS keys with care, adhering to your organization's security policies and best practices.
By following these steps, you can successfully change the encryption setting of your S3 bucket from SSE-S3 to SSE-KMS using the AWS CLI.
References:
Using dual-layer server-side encryption with AWS KMS keys (DSSE-KMS)
Using server-side encryption with customer-provided keys (SSE-C)
Specifying server-side encryption with Amazon S3 managed keys (SSE-S3)
https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketEncryption.html
AWS Key Management Service