Amazon S3 encryption

Encryption allows you to store objects in such a way that only an entity that has the encryption key, or access to the encryption key can access that object.

S3 Encryption types

There are five ways in which you can encrypt objects that you write to S3.

S3 Encryption Options

S3 Server Side Encryption using Amazon S3 Managed Keys

You can encrypt data in S3 using keys that are managed completely by S3. This uses AES-256 encryption. There are no additional charges for using this encryption. Use this if your company does not have a policy around encryption keys and you are ok with AWS owning your keys. Encryption via code is requested by using the x-amz-server-side-encryption header. You can write a bucket policy that denies upload requests that do not contain this header

S3 Server Side Encryption using keys stored in AWS KMS (AWS Or Customer managed)

AWS KMS allows you to create encryption keys and these encryption keys can be used to encrypt objects in S3. There are two ways to create encryption keys (also known as Customer Master Key or CMK). The first way is to let AWS create a key for you. When you use this option, AWS creates a key called aws/s3

S3 key created by AWS KMS

The other way is to create a key yourself in KMS using your own key material. The advantage of this method is that you can manage (rotate) the keys yourself and you own the key material.

For keys stored in AWS KMS there is an overhead as well. You are charged for using KMS as specified here. You can reduce the charge if you configure S3 bucket keys. To specify SSE using KMS pass in the header x-amz-server-side-encryption with a value of aws:kms. You can then also pass in the header x-amz-server-side-encryption-aws-kms-key-id

S3 Server Side Encryption using Customer keys

In the first case we had keys managed by S3, then we say keys managed by KMS (and the key generated by either AWS or the customer). In the third case we look at keys that are completely with the client. i.e. AWS does not manage the keys at all. You pass in the key when you upload objects and then pass in the same key to download the object.

Here’s an example in python to do that

import boto3
import os

BUCKET = 'studytrails-s3-course'
KEY = os.urandom(32)
s3 = boto3.client('s3')

# Upload encrypted object
s3.put_object(Bucket=BUCKET,
              Key='encryptedObject',
              Body=b'a,b,c',
              SSECustomerKey=KEY,
              SSECustomerAlgorithm='AES256')

# Upload unencrypted object
s3.put_object(Bucket=BUCKET,
              Key='unencryptedObject',
              Body=b'a,b,c')

# Getting the object:
print("Getting S3 object...")
# Note how we're using the same ``KEY`` we created earlier.
response = s3.get_object(Bucket=BUCKET,
                         Key='encryptedObject',
                         SSECustomerKey=KEY,
                         SSECustomerAlgorithm='AES256')
print("Done, response body:")
print(response['Body'].read())

S3 Client side encryption

You can encrypt a file in your own application. You can either use your own key, or use keys managed in KMS. There is no client for Python currently.

Leave a Comment