AWS Storage Blog
Understanding Amazon S3 client-side encryption options
Encryption serves a fundamental role in securing sensitive data both in transit and at rest. Server-side encryption offers simplicity and ease of implementation, with data encrypted where stored, and enables seamless integration with other services. In contrast, client-side encryption secures data where ingested or created, and offers additional capabilities to meet specific security requirements around data sovereignty and encryption key ownership. However, to implement client-side encryption, users must store keys, control access, and manage the encryption process.
Amazon S3 provides multiple encryption options to meet diverse security needs. For server-side encryption, S3 offers native encryption with Amazon S3 managed keys (SSE-S3), which is enabled by default and encrypts all new object uploads to an S3 bucket. Or you can choose to configure buckets to use server-side encryption with AWS Key Management Service (AWS KMS) keys (SSE-KMS), that allows more key controls for individual users, more flexible key rotation policies, and enhanced auditing. Most users are best served with S3 server-side encryption with SSE-S3 or SSE-KMS because they provide strong security with minimal implementation complexity. However, alternative encryption options may be necessary when you have unique requirements or need to encrypt data locally with keys you own outside the cloud. For these situations, users can choose client-side encryption Amazon S3 Encryption Client and AWS Encryption SDK, thought these require additional development effort and key management responsibilities. Alternatively, users can explore server-side encryption with customer-provided keys (SSE-C).
In this post, we explore the S3 Encryption Client, the AWS Encryption SDK and SSE-C, including using them, their benefits, and other considerations. Evaluating these alternatives allows users to choose the approach that best fits their encryption requirements while minimizing disruption to existing application architectures. When evaluating the different client-side encryption alternatives, we focus on the complexity and development effort necessary and integration with other AWS services.
Amazon S3 Encryption Client
The Amazon S3 Encryption Client is an SDK that encrypts data on the client system before it is uploaded to Amazon S3. This SDK integration automatically encrypts and decrypts your data as part of Amazon S3 PutObject and GetObject requests. Therefore, Amazon S3 receives objects already encrypted. Data is protected in transit and at rest, and isn’t exposed to a third-party including AWS. Using client-side encryption (CSE) with AWS KMS customer managed keys is referred to as CSE-KMS.
To encrypt your object, the S3 Encryption Client uses envelope encryption. A wrapping key protects the data encryption keys used to encrypt objects. The object and data key are encrypted with the AES-GCM encryption algorithm. You can manage the wrapping key in the following ways:
- Use a web service designed for this purpose, such as AWS KMS.
- Use a hardware security module(HSM) such as those offered by AWS CloudHSM.
- Use other key management tools and services.
Figure 1: Amazon S3 Encryption Client envelope encryption
Amazon S3 Encryption Client supports several programming languages: C++, Go, Java, .NET, PHP, and Ruby. The developer guide provides detailed instructions for managing wrapping keys and instantiating the client. A specific code example for Java covers each step.
Process for using S3 Encryption Client when using an RSA keypair as wrapping key:
- Specify your wrapping key and create a keyring when you instantiate your client.
- Encrypt your plaintext object by calling PutObject.
- The S3 Encryption Client does the following:
- Provides the encryption materials: one plaintext data key and one copy of that data key encrypted by your wrapping key.
- Use the plaintext data key to encrypt your object, then discard the plaintext data key.
- Upload the encrypted data key and the encrypted object to S3 as part of the PutObject call.
- Decrypt your encrypted object by calling GetObject.
- The S3 Encryption Client does the following:
- Uses your wrapping key to decrypt the encrypted data key.
- Uses the plaintext data key to decrypt the object, discard the plaintext data key, and return the plaintext object as part of the GetObject call.
The Amazon Encryption client also supports other Amazon services, including:
- Amazon Athena: Runs queries on data encrypted with CSE-KMS. Athena supports reading from encrypted table data, reading/writing encrypted query results, and inserting data into an encrypted table (see this AWS News blog and Athena documentation).
- Amazon Redshift: Loads encrypted data files from Amazon S3. The COPY command supports client-side encryption using a symmetric root key (see Redshift documentation). Redshift Spectrum does not support Amazon S3 client-side encryption.
- Amazon EMR: Supports both CSE-KMS and a custom Java class that provides the client-side wrapper key (CSE-C) to store data with EMRFS in Amazon S3 (see EMR documentation).
Benefits
- Key material can be maintained outside of AWS.
- Data is encrypted with AES-GCM encryption before leaving the client, ensuring protection throughout its entire journey from transmission to storage.
- Available in several programming languages.
- Uses existing code with Amazon S3 API calls that include encryption (for example GetObject, PutObject).
- Some integration with Amazon Athena, Amazon Redshift, and Amazon EMR.
- Supports AWS KMS for wrapper key management and auditing (wrapper keys in AWS KMS do not leave the service unencrypted).
- Coexists with other Amazon S3 server-side encryptions.
- Supports envelope encryption, separating the data key from the wrapper key, and optionally encrypting each object with a unique data key.
Considerations
- CSE-KMS requires more API calls to encrypt and decrypt data keys. It is similar to SSE-KMS from a request cost perspective.
- If not using AWS KMS for wrapper key management, then users are responsible for the availability, durability, persistence, rotation, and lifecycle of the key material. Moreover, not using AWS KMS eliminates the ability to integrate directly with Athena and Amazon EMR.
- Uses client-side CPU for encryption operations.
AWS Encryption SDK
AWS Encryption SDK is a general-purpose client-side encryption library that doesn’t necessitate specific AWS service integrations or dependencies. It is developed in open source repositories on GitHub. The AWS Encryption SDK provides functions to encrypt/decrypt strings and streams. When using the AWS Encryption SDK, Amazon S3 receives your objects already encrypted and does not play a role in encrypting or decrypting objects.
Although similar, the AWS Encryption SDK and Amazon S3 Encryption Client serve different purposes. The AWS Encryption SDK encrypts data that you can store anywhere, while the Amazon S3 Encryption Client is specific to Amazon S3. The AWS Encryption SDK and the Amazon S3 Encryption Client are not compatible because they produce ciphertexts with different data formats.
The AWS Encryption SDK natively supports AWS KMS and is supported in several programming languages: Java, Python, C, C#/.NET, and JavaScript. For more information see the documentation and examples.
To Encrypt: The AWS Encryption SDK uses envelope encryption to protect your data. Each object is encrypted under a unique data key and the data key is encrypted by the wrapping key specified. The encryption method returns an encrypted message that contains the encrypted data, the encrypted data keys, and other metadata. By default, the AWS Encryption SDK uses the AES-GCM encryption algorithm with a 256-bit encryption key.
To Decrypt: The AWS Encryption SDK uses the wrapping key specified to decrypt the data key. Then it can decrypt the ciphertext and return a plaintext message.
Benefits
- Key material can be maintained outside of AWS.
- Data is encrypted with AES-GCM encryption before leaving the client, ensuring protection throughout its entire journey from transmission to storage.
- Available in several programming languages. Encrypted objects are interoperable across supported languages.
- Supports AWS KMS keys to protect your data (documentation), including multi-Region keys in AWS KMS.
- Coexists with other Amazon S3 server-side encryptions.
- Uses envelope encryption.
Considerations
- Existing applications would need modification for encryption/decryption flows.
- Other than AWS KMS, AWS Encryption SDK does not provide integrations with AWS services.
- The AWS Encryption SDK cannot decrypt data encrypted by other AWS services like the Amazon S3 Encryption Clientor the AWS Database Encryption SDK for DynamoDB.
- Uses client-side CPU for encryption operations.
Server-side encryption with customer-provided keys (SSE-C)
For users that need the ability to maintain direct possession and full control over the encryption keys but also want the simplicity of a server-side encryption, SSE-C allows Amazon S3 to perform server-side encryption with customer-provided keys. The user is responsible for providing the encryption key during upload or download and Amazon S3 is responsible for encrypting and decrypting the object. Amazon S3 SSE-C uses AES-256 encryption to encrypt an object with the customer-provided key when an object is uploaded. After the object is uploaded to Amazon S3, the encryption key is wiped from memory. When the object is retrieved, the same customer-provided key that was used for encryption must also be provided to decrypt the object. To decrypt the object, Amazon S3 checks to see if the customer-provided key matches the key used for encryption. If the customer-provided key is verified as a match, then Amazon S3 decrypts the object as it is downloaded to the client. For more detailed information about SSE-C, review the documentation and code examples.
The process for using SSE-C encryption works as follows:
- Generate a 256-bit encryption key and securely send it using TLS to Amazon S3 when uploading a new object.
- Amazon S3 uses the encryption key that you provide to apply AES-256 encryption to the object.
- Amazon S3 removes the encryption key from memory.
- Provide the same encryption key as part of the request when retrieving an object.
Steps for SSE-C encryption using AWS Command Line Interface (AWS CLI):
- Create an S3 bucket or identify the S3 bucket that you would like to use to for uploading the encrypted object. In this example, we use the S3 bucket named
amzn-s3-demo-bucket
. You must create your own bucket and replaceamzn-s3-demo-bucket
in the following command with your own bucket name.
aws s3 mb s3://amzn-s3-demo-bucket
- Create an object. In this step, we create an object called txt.
echo "Lorem ipsum dolor sit amet" > example.txt
- Generate a key key to encrypt example.txt. This is a simple example of key creation. When creating your own key, make sure that it follows security practices such as the CIA Triad.
openssl rand -out example.key 32
- Upload the txt object to the amzn-s3-demo-bucket using the example.key that we created. When using SSE-C encryption, Amazon S3 encrypts the example.txt object for us. You must replace amzn-s3-demo-bucket in the following command with the name of your bucket.
aws s3 cp example.txt s3://amzn-s3-demo-bucket/example.txt --sse-c AES256 --sse-c-key fileb://example.key
- To retrieve the item from the bucket, you must provide the key that was originally used for encryption. Make sure to note where you store the key because if you lose the key, you will not be able to decrypt your object. Replace
amzn-s3-demo-bucket
in the following command with the name of your bucket.
aws s3 cp s3://amzn-s3-demo-bucket/example.txt example-downloaded.txt --sse-c AES256 --sse-c-key fileb://example.key
Benefits
- Maintain direct possession and control of encryption keys.
- No need to implement or maintain code for encryption and decryption operations.
- Ability to enforce encryption from the server-side, necessitating an encryption key for uploads.
- Integrated with existing Amazon S3 API and AWS SDK implementation.
- Amazon S3 handles encryption and decryption transparently for data at rest.
- No additional charges for using SSE-C beyond standard Amazon S3 request costs.
Considerations
- Limited service integration: AWS services such as Amazon Redshift and Amazon Athena do not support reading SSE-C encrypted data directly from Amazon S3.
- Users are responsible for the availability, durability, persistence, rotation, and lifecycle of the key material.
- Need to securely send the encryption key to Amazon S3 with every applicable API request.
- Does not provide envelope encryption to separate data keys from wrapper keys.
- Not compatible with other Amazon S3 server-side encryptions. Adopting SSE-C would necessitate re-encrypting datasets already using SSE-S3 or SSE-KMS.
- Data is encrypted in-transit through TLS and server-side by Amazon S3 using the provided keys for encryption at-rest.
Additional considerations
When using the encryption options discussed in this post, you are responsible for managing the mapping between encryption keys and the objects encrypted by these keys. As the encryption keys are managed client-side, you are also responsible for implementing durability capabilities and security measures, such as key rotation policies and lifecycle procedures on the client side. If you do not have encryption key infrastructure, then AWS recommends using AWS KMS.
Conclusion
Although most users are best served with Amazon S3 server-side encryption with Amazon S3 managed keys or controlling their own keys with AWS KMS, you may have data security or policy requirements that necessitate client-side encryption or server-side encryption with client-provided keys. Client-side encryption offers the ability to maintain direct possession and full control over your encryption keys and provides data encryption end-to-end to achieve unique security requirements. However, client-side encryption also makes you solely responsible for the security, durability, and availability of your encryption key material.
This post explored three alternatives to SSE-S3 and SSE-KMS encryption options that allow users to use Amazon S3 while keeping their data encryption keys outside of your AWS environment. The options covered the Amazon S3 Encryption Client, the AWS Encryption SDK and SSE-C. Evaluating the benefits and considerations of each approach in terms of complexity, service integration, key management features, supported programing languages, and policy compliance allows users to choose the solution that best fits their encryption needs while minimizing disruption to existing application architectures.
For more information, review the official documentation for each option:
- Amazon S3 Encryption Client Developer Guide
- AWS Encryption SDK Developer Guide
- Server-Side Encryption with Customer-Provided Keys (SSE-C)
For hands-on implementation, explore these code examples:
Learn more about key management best practices with AWS Key Management Service and consider exploring AWS CloudHSM for hardware-based key management requirements.