Encrypting S3 Objects Using SSE-KMS

Linn Latt OoLinn Latt Oo
4 min read

When storing sensitive data in Amazon S3, it's critical to make sure it's protected. AWS provides multiple encryption options, and one of the most secure and flexible methods is server-side encryption with AWS Key Management Service (SSE-KMS) using a customer-managed key (CMK).

In this post, I’ll walk you through:

  • Creating your own KMS key

  • Using that key to encrypt files uploaded to S3

  • Enforcing encryption via bucket policies

Key Concepts in AWS KMS

  • Symmetric Key – A single key is used for both encrypting and decrypting data.

  • Asymmetric Key – Uses a key pair: a public key to encrypt and a private key to decrypt.

  • AWS-Managed Key – Automatically created and managed by AWS.

  • Customer-Managed Key (CMK) – A key you create, configure, and control.

  • Key Rotation – Periodically changes the key's internal material to improve security.

For encrypting S3 files, a symmetric CMK is the most common and practical option.

Create a Customer-Managed KMS Key

Search for “KMS” in the AWS Console, click Key Management Service, then Customer-managed keys > Create key.

Keep the default settings to generate a symmetric key with AWS-provided key material. On the next screen, give your key an alias and optionally add a description to help identify it later.

Continue with the default administrative permissions, which define who can manage the key but not use it for encryption. Then, set the usage permissions to decide who can perform cryptographic operations like encrypting and decrypting data.

Finally, review the policy details, click Finish, and make sure your key appears in the list with the status “Enabled.” The key is now ready to be used for securing S3 objects with server-side encryption.

Creating an S3 Bucket with Default SSE-KMS Encryption

To ensure all objects stored in our S3 bucket are encrypted with our own AWS KMS Customer Managed Key (CMK), we can configure default server-side encryption during bucket creation.

This way, every object uploaded to the bucket will be automatically encrypted without requiring users to explicitly select an encryption method during upload.

Navigate to the Amazon S3 Console and click Create bucket. Enter a unique bucket name and select a region.

Scroll down to the Default encryption section and configure the following:

  • Encryption type:
    ✅ Select Server-side encryption with AWS Key Management Service keys (SSE-KMS).

  • AWS KMS key:
    ✅ Choose your Customer Managed Key (CMK) from the dropdown.
    (You can also click "Create a KMS key" if you don’t have one yet.)

  • Bucket Key:
    ✅ Enable Bucket Key to reduce AWS KMS request costs.

Then, click Create bucket at the bottom of the page.

Verify Encryption

Go to your S3 bucket in the console and click UploadAdd Files. There's no need to configure encryption, it's handled automatically!

Enforcing SSE-KMS using Bucket Policy (Optional)

Even with default encryption, it’s good security practice to enforce SSE-KMS through a bucket policy, especially if others upload via SDK, CLI, or APIs.

In the S3 bucket console, click the Permissions tab followed by Bucket Policy to open the Bucket policy editor.

Insert the following bucket policy into the editor:

{
    "Version": "2012-10-17",
    "Id": "RequireSSEKMS",
    "Statement": [
        {
            "Sid": "DenyUploadIfNotSSEKMSEncrypted",
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::<your-bucket-name>/*”,
            "Condition": {
                "StringNotEquals": {
                    "s3:x-amz-server-side-encryption-aws-kms-key-id": "arn:aws:kms:<region>:<account_id>:key/<key-id>"
                }
            }
        }
    ]
}

Replace <Your_Bucket_Name> and <region>:<account_id>:key/<key-id> with your actual name.

Attempt to upload a file by changing the encryption configuring. The upload should fail.

Retry the upload, this time without changing the encryption configuration. The upload should succeed.

These steps are configuring an S3 bucket policy to require SSE-KMS encryption for any new objects uploaded to the bucket. This ensures that all data stored in the bucket is encrypted according to your specified requirements.

Conclusion

In this article, we explored the process of encrypting S3 objects using SSE-KMS, from creating a Customer-Managed Key to enforcing encryption policies. By implementing these practices, you can significantly enhance the security of your data stored in AWS S3.

0
Subscribe to my newsletter

Read articles from Linn Latt Oo directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Linn Latt Oo
Linn Latt Oo