An Overview of AWS S3 Encryption at Rest

For those of you who are working through your AWS Solutions Architect Associate Exam prep (and to help with my own exam prep :-), I wanted to provide a high-level overview of encryption in S3 and the various different options that are available for encrypting Objects at rest and in transit.

For those of you interested in further reading on this specific topic, I suggest the both the AWS Security Blog and AWS S3 Documentation, specifically Protecting Data using Encryption.

Overview

When we apply encryption at rest to Objects in S3, we do not ‘encrypt S3’ or encrypt an S3 Bucket. Instead, encryption of data within an S3 Object can be broken down into two distinct categories:

  1. Server Side Encryption – data is sent in plaintext (but over an secure transport) to S3, where it is encrypted as the Object is written to disk within the AWS data-centres; similarly, S3 decrypts the Object when it is retrieved from storage and returned to the caller (again over an secure transport).
  2. Client Side Encryption – data is encrypted by the client application before it is sent to S3; when the Object is retrieved, it is returned to the client application in its original encrypted form and the client must decrypt the data before it can be used. To be covered in the next post.

Lets dive into each of these options in more detail.

SSE-S3 – Server-Side Encryption, with encryption keys managed by S3

With SSE-S3, AWS manages all of the heavy lifting to achieve encryption at rest for your data in S3. Every object is encrypted with a unique Data-Key, which is then encrypted with a separate Master-Key. The Master-Key is managed by AWS and rotated regularly. S3 uses AES-256 to encrypt both the Object and the Data-Key.

Note that S3 Bucket Policies can be applied to enforce server-side encryption of Objects stored in a Bucket.

SSE-S3 can be enabled by selecting the ‘Amazon S3 Master Key’ option when uploading a new Object…

…and is displayed with AES-256 encryption enabled when looking at the Object properties:

For more information about SSE-S3, see the AWS documentation Protecting Data Using Server-Side Encryption with Amazon S3-Managed Encryption Keys (SSE-S3).

 

SSE-KMS – Server-Side Encryption, with Master Keys managed by AWS KMS (Key Management Service).

With SSE-KMS, AWS manages Master Keys within KMS, a service that combines secure, highly available hardware and software to provide a key management system scaled for the cloud. Every object is encrypted with a unique Data-Key, which is then encrypted with the Master-Key as defined by KMS. S3 uses AES-256 to encrypt both the Object and the Data-Key.

KMS ensures that the Master-Key never leaves its security boundary, helping customers meet encryption-related compliance requirements. Furthermore, the use of custom Master-Keys can be audited and permissions can be applied to protect against unauthorized access and use of the and any data encrypted with that Master-Key.

The Master-Key is managed by KMS and either a default key can be created by KMS (that is unique to your Account, the service being used (S3) and the Region in which the service is hosted), or a custom Master-Key can be created through IAM (Identity and Access Management) and stored within KMS. When a custom Master-Key is used, an account admin is responsible for creating, rotating, disabling and defining access controls for the key.

Note that S3 Bucket Policies can be applied to enforce server-side encryption of Objects stored in a Bucket.

SSE-KMS can be enabled by selecting the ‘AWS KMS master key’ option when uploading a new Object:

…and is displayed with KMS encryption enabled when looking at the Object properties (interestingly the old portal provides more information – the Customer Master Key in use – than the new portal):

For more information about SSE-KMS, see the AWS documentation Protecting Data Using Server-Side Encryption with AWS KMS–Managed Keys (SSE-KMS).

 

SSE-C – Service-Side Encryption with Customer provided keys.

With SSE-C, S3 manages the encryption of data as it is written to an Object and decryption of an Object when it is requested, but the customer supplies the relevant encryption key during the API request. The customer is therefore responsible for managing their encryption keys, including the secure storage, creation, rotation and disabling of keys.

When an Object is uploaded, S3 uses the supplied encryption key to apply AES-256 encryption to the data supplied in the request and then removes the encryption key from memory. While processing the upload request, S3 creates a randomly salted HMAC (Hashed Message Authentication Code) from the encryption key in order to validate future requests – this HMAC cannot be used to derive the value of the encryption key or decrypt the contents of the encrypted Object.

When an Object is retrieved, the customer supplies the encryption key again as part of the API request. S3 will verify that the supplied key matches and then decrypts the object, returning the decrypted plain-text over a secure transport.

Note that S3 will reject any requested for SSE-C if they are made over (plain) HTTP.

SSE-C can only be used when upload an Object through the S3 API – it cannot be used through the Management Console.

For more information about SSE-S3, see the AWS documentation Protecting Data Using Server-Side Encryption with Customer-Provided Encryption Keys (SSE-C).