AWS Developer Tools Blog

Amazon S3 Server-Side Encryption with Customer-Provided Keys

Amazon S3 recently launched a new feature that lets developers take advantage of server-side encryption, but still control their encryption keys. This new server-side encryption mode for Amazon S3 is called Server-Side Encryption with Customer-Provided Keys (SSE-C).

Using server-side encryption in Amazon S3 with your own encryption keys is easy using the AWS SDK for Java. Just pass along an instance of SSECustomerKey with your requests to Amazon S3.

The SSECustomerKey class holds your encryption key material for AES-256 encryption and an optional MD5 for checking the data integrity of the encryption key when it gets passed to Amazon S3. You can specify your AES-256 encryption key as a Java SecretKey object, a byte[] of the raw key material, or as a base64-encoded string. The MD5 is optional since the SDK will automatically generate it for you to ensure your encryption key is transmitted to Amazon S3 without any corruption.

Here’s an example of using server-side encryption with a customer-provided encryption key using the AWS SDK for Java:

AmazonS3 s3 = new AmazonS3Client();
SecretKey secretKey = loadMyEncryptionKey();
SSECustomerKey sseCustomerKey = new SSECustomerKey(secretKey);

// Upload a file that will be encrypted with our key once it gets to S3
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key, file)
        .withSSECustomerKey(sseCustomerKey);
s3.putObject(putObjectRequest);

// To download data encrypted with SSE-C, you must provide the 
// correct SSECustomerKey, otherwise the request will fail
GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, key)
        .withSSECustomerKey(sseCustomerKey);
S3Object s3Object = s3.getObject(getObjectRequest);

You can use server-side encryption with customer-provided keys with these Amazon S3 operations in the AWS SDK for Java:

You can also take advantage of server-side encryption with customer-provided keys using the Amazon S3 TransferManager API. Just specify your SSECustomerKey in the same way as you do when using AmazonS3Client:

TransferManager tm = new TransferManager();

PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key, file)
        .withSSECustomerKey(sseCustomerKey);
Upload upload = tm.upload(putObjectRequest);

// TransferManager processes transfers asynchronously
// waitForCompletion will block the current thread until the transfer finishes
upload.waitForCompletion();

GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, key)
        .withSSECustomerKey(sseCustomerKey);
Download download = tm.download(getObjectRequest, myFile);

Do you have data that requires being encrypted at rest? How are you planning on using server-side encryption with customer-provided keys?