Using server-side encryption with Amazon Key Management Service (SSE-KMS) - Amazon Simple Storage Service
Services or capabilities described in Amazon Web Services documentation might vary by Region. To see the differences applicable to the China Regions, see Getting Started with Amazon Web Services in China.

Using server-side encryption with Amazon Key Management Service (SSE-KMS)

Server-side encryption is the encryption of data at its destination by the application or service that receives it. Amazon Key Management Service (Amazon KMS) is a service that combines secure, highly available hardware and software to provide a key management system scaled for the cloud. Amazon S3 uses Amazon KMS keys to encrypt your Amazon S3 objects. Amazon KMS encrypts only the object data. The checksum, along with the specified algorithm, are stored as part of the object's metadata. If server-side encryption is requested for the object, then the checksum is stored in encrypted form.

If you use KMS keys, you can use Amazon KMS through the Amazon Web Services Management Console or the Amazon KMS APIs to do the following:

  • Centrally create KMS keys

  • Define the policies that control how KMS keys can be used

  • Audit their usage to prove that they are being used correctly

The security controls in Amazon KMS can help you meet encryption-related compliance requirements. You can use these KMS keys to protect your data in Amazon S3 buckets. When you use SSE-KMS encryption with an S3 bucket, the Amazon KMS keys must be in the same Region as the bucket.

There are additional charges for using Amazon KMS keys. For more information, see Amazon KMS key concepts in the Amazon Key Management Service Developer Guide and Amazon KMS pricing.


To upload an object encrypted with an Amazon KMS key to Amazon S3, you need kms:GenerateDataKey permissions on the key. To download an object encrypted with an Amazon KMS key, you need kms:Decrypt permissions. For information about Amazon KMS permissions required for multipart upload, see Multipart upload API and permissions.

Amazon KMS keys

When you use server-side encryption with Amazon KMS (SSE-KMS), you can use the default Amazon managed key, or you can specify a customer managed key that you have already created. Amazon KMS uses envelope encryption to further protect your data. Envelope encryption is the practice of encrypting your plaintext data with a data key, and then encrypting that data key with a root key.

If you don't specify a customer managed key, Amazon S3 automatically creates an Amazon KMS key in your Amazon Web Services account the first time that you add an object encrypted with SSE-KMS to a bucket. By default, Amazon S3 uses this KMS key for SSE-KMS.

If you want to use a customer managed key for SSE-KMS, create the customer managed key before you configure SSE-KMS. Then, when you configure SSE-KMS for your bucket, specify the existing customer managed key.

Creating a customer managed key gives you more flexibility and control. For example, you can create, rotate, and disable customer managed keys. You can also define access controls and audit the customer managed key that you use to protect your data. For more information about customer managed and Amazon managed keys, see Amazon KMS concepts in the Amazon Key Management Service Developer Guide.

If you choose to encrypt your data using a KMS key or customer managed key, Amazon KMS and Amazon S3 perform the following actions:

  • Amazon S3 requests a plaintext data key and a copy of the key encrypted under the specified KMS key.

  • Amazon KMS generates a data key, encrypts it under the KMS key, and sends both the plaintext data key and the encrypted data key to Amazon S3.

  • Amazon S3 encrypts the data using the data key and removes the plaintext key from memory as soon as possible after use.

  • Amazon S3 stores the encrypted data key as metadata with the encrypted data.

When you request that your data be decrypted, Amazon S3 and Amazon KMS perform the following actions:

  • Amazon S3 sends the encrypted data key to Amazon KMS.

  • Amazon KMS decrypts the key by using the same KMS key and returns the plaintext data key to Amazon S3.

  • Amazon S3 decrypts the ciphertext and removes the plaintext data key from memory as soon as possible.


When you use an Amazon KMS key for server-side encryption in Amazon S3, you must choose a symmetric encryption KMS key. Amazon S3 supports only symmetric encryption KMS keys and not asymmetric keys. For more information, see Using Symmetric and Asymmetric Keys in the Amazon Key Management Service Developer Guide.

To identify requests that specify SSE-KMS, you can use the All SSE-KMS requests and % all SSE-KMS requests metrics in Amazon S3 Storage Lens metrics. S3 Storage Lens is a cloud-storage analytics feature that you can use to gain organization-wide visibility into object-storage usage and activity. For more information, see Assessing your storage activity and usage with S3 Storage Lens. For a complete list of metrics, see S3 Storage Lens metrics glossary.

Amazon S3 Bucket Keys

When you configure server-side encryption using Amazon KMS (SSE-KMS), you can configure your bucket to use S3 Bucket Keys for SSE-KMS. Using a bucket-level key for SSE-KMS can reduce your Amazon KMS request costs by up to 99 percent by decreasing the request traffic from Amazon S3 to Amazon KMS.

When you configure your bucket to use S3 Bucket Keys for SSE-KMS on new objects, Amazon KMS generates a bucket-level key that is used to create unique data keys for objects in the bucket. This bucket key is used for a time-limited period within Amazon S3, further reducing the need for Amazon S3 to make requests to Amazon KMS to complete encryption operations. For more information about using S3 Bucket Keys, see Reducing the cost of SSE-KMS with Amazon S3 Bucket Keys.

Requiring server-side encryption

To require server-side encryption of all objects in a particular Amazon S3 bucket, you can use a policy. For example, the following bucket policy denies the upload object (s3:PutObject) permission to everyone if the request does not include the x-amz-server-side-encryption header requesting server-side encryption with SSE-KMS.

{ "Version":"2012-10-17", "Id":"PutObjectPolicy", "Statement":[{ "Sid":"DenyUnEncryptedObjectUploads", "Effect":"Deny", "Principal":"*", "Action":"s3:PutObject", "Resource":"arn:aws-cn:s3:::DOC-EXAMPLE-BUCKET1/*", "Condition":{ "StringNotEquals":{ "s3:x-amz-server-side-encryption":"aws:kms" } } } ] }

To require that a particular Amazon KMS key be used to encrypt the objects in a bucket, you can use the s3:x-amz-server-side-encryption-aws-kms-key-id condition key. To specify the KMS key, you must use a key Amazon Resource Name (ARN) that is in the "arn:aws-cn:kms:region:acct-id:key/key-id" format.


When you upload an object, you can specify the KMS key using the x-amz-server-side-encryption-aws-kms-key-id header. If the header is not present in the request, Amazon S3 assumes that you want to use the Amazon managed key. Regardless, the Amazon KMS key ID that Amazon S3 uses for object encryption must match the Amazon KMS key ID in the policy, otherwise Amazon S3 denies the request.

For a complete list of Amazon S3‐specific condition keys, see Condition keys for Amazon S3.

Encryption context

An encryption context is a set of key-value pairs that contains additional contextual information about the data. The encryption context is not encrypted. When an encryption context is specified for an encryption operation, Amazon S3 must specify the same encryption context for the decryption operation. Otherwise, the decryption fails. Amazon KMS uses the encryption context as additional authenticated data (AAD) to support authenticated encryption. For more information about the encryption context, see Encryption context in the Amazon Key Management Service Developer Guide.

Amazon S3 automatically uses the object or bucket Amazon Resource Name (ARN) as the encryption context pair:

  • If you use SSE-KMS without enabling an S3 Bucket Key, the object ARN is used as the encryption context.

  • If you use SSE-KMS and enable an S3 Bucket Key, the bucket ARN is used as the encryption context. For more information about S3 Bucket Keys, see Reducing the cost of SSE-KMS with Amazon S3 Bucket Keys.


You can optionally provide an additional encryption context pair using the x-amz-server-side-encryption-context header in an s3:PutObject request. However, because the encryption context is not encrypted, make sure it does not include sensitive information. Amazon S3 stores this additional key pair alongside the default encryption context. When it processes your PUT request, Amazon S3 appends the default encryption context of aws:s3:arn to the one that you provide.

You can use the encryption context to identify and categorize your cryptographic operations. You can also use the default encryption context ARN value to track relevant requests in Amazon CloudTrail by viewing which Amazon S3 ARN was used with which encryption key.

In the requestParameters field of a CloudTrail log file, the encryption context looks similar to the following one.

"encryptionContext": { "aws:s3:arn": "arn:aws-cn:s3:::DOC-EXAMPLE-BUCKET1/file_name" }

When you use SSE-KMS with the optional S3 Bucket Keys feature, the encryption context value is the ARN of the bucket.

"encryptionContext": { "aws:s3:arn": "arn:aws-cn:s3:::DOC-EXAMPLE-BUCKET1" }

Amazon Signature Version 4

Signature Version 4 is the process of adding authentication information to Amazon requests sent by HTTP. For security, most requests to Amazon must be signed with an access key, which consists of an access key ID and secret access key. These two keys are commonly referred to as your security credentials. For more information, see Authenticating Requests (Amazon Signature Version 4) and Signature Version 4 signing process.

  • All GET and PUT requests for Amazon KMS encrypted objects must be made using Secure Sockets Layer (SSL) or Transport Layer Security (TLS). Requests must also be signed using valid credentials, such as Amazon Signature Version 4 (or Amazon Signature Version 2).

  • If your object uses SSE-KMS, don't send encryption request headers for GET requests and HEAD requests, or you’ll get an HTTP 400 BadRequest error.