

# What is the Amazon S3 Encryption Client?


**Note**  
This documentation describes the Amazon S3 Encryption Client version 3.*x* and newer, which is an independent library. For information about previous versions of the Amazon S3 Encryption Client, see the AWS SDK Developer Guide for your programming language.

The Amazon S3 Encryption Client is a client-side encryption library that enables you to encrypt an object locally to ensure its security before passing it to [Amazon Simple Storage Service](https://docs.aws.amazon.com/AmazonS3/latest/userguide/Welcome.html) (Amazon S3). Amazon S3 receives your object already encrypted; it does not play a role in encrypting or decrypting it. After you instantiate the Amazon S3 Encryption Client, your objects are automatically encrypted and decrypted as part of your Amazon S3 `PutObject` and `GetObject` requests. The Amazon S3 Encryption Client is provided free of charge under the Apache 2.0 license.

The Amazon S3 Encryption Client is supported in the following programming languages and platforms. This guide focuses on version 4.x of the [Amazon S3 Encryption Client for Java](java.md) and [Amazon S3 Encryption Client for Go](go.md). For more information on the remaining language implementations, see their respective AWS SDK Developer Guides.
+ [AWS SDK for C\$1\$1](https://docs.aws.amazon.com/sdk-for-cpp/latest/developer-guide/)
+ [AWS SDK for Go](https://github.com/aws/amazon-s3-encryption-client-go)
+ [AWS SDK for Java](https://github.com/aws/amazon-s3-encryption-client-java)
+ [AWS SDK for .NET](https://docs.aws.amazon.com/sdk-for-net/latest/developer-guide/kms-keys-s3-encryption.html)
+ [AWS SDK for Ruby](https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/EncryptionV2/Client.html)
+ [AWS SDK for PHP](https://docs.aws.amazon.com/sdk-for-php/latest/developer-guide/s3-encryption-client.html)

The Amazon S3 Encryption Client provides:

**A default implementation that adheres to cryptography best practices**  
By default, the Amazon S3 Encryption Client generates a unique data key for each object that it encrypts. This follows the cryptography best practice of using unique data keys for each encryption operation.  
The Amazon S3 Encryption Client encrypts your objects using a secure, authenticated, symmetric key algorithm.

**A framework for protecting data keys with wrapping keys**  
The Amazon S3 Encryption Client protects the data keys that encrypt your objects by encrypting them under a [wrapping key](concepts.md#wrapping-key). With the Amazon S3 Encryption Client, you define a wrapping key by passing the key to the Amazon S3 Encryption Client, which it uses to optimize its settings.

# Amazon S3 Encryption Client concepts
Terms and concepts

**Note**  
This documentation describes the Amazon S3 Encryption Client version 3.*x* and newer, which is an independent library. For information about previous versions of the Amazon S3 Encryption Client, see the AWS SDK Developer Guide for your programming language.

This topic introduces the concepts and terminology used in the Amazon S3 Encryption Client. It's designed to help you understand how the Amazon S3 Encryption Client works and the terms we use to describe it.

**Topics**
+ [

## Envelope encryption
](#envelope-encryption)
+ [

## Data key
](#data-key)
+ [

## Wrapping key
](#wrapping-key)
+ [

## Keyrings
](#keyring)
+ [

## Supported encryption algorithms
](#algorithm)
+ [

## Cryptographic materials manager
](#crypt-materials-manager)
+ [

## Encryption context
](#encryption-context)
+ [

## Instruction files
](#instruction-files)
+ [

## Key commitment
](#key-commitment)
+ [

## Commitment policy
](#commitment-policy)

## Envelope encryption


The security of your encrypted object depends in part on protecting the data key that can decrypt it. One accepted best practice for protecting the data key is to encrypt it. To do this, you need another encryption key, known as a *key-encryption key* or [wrapping key](#wrapping-key). The practice of using a wrapping key to encrypt data keys is known as *envelope encryption*.

**Protecting data keys**  
The Amazon S3 Encryption Client encrypts each object with a unique [data key](#data-key). Then it encrypts the data key under the wrapping key you specify. It stores the encrypted data key with the encrypted object that the `PutObject` request uploads to Amazon S3.  

![\[Envelope encryption with the Amazon S3 Encryption Client\]](http://docs.aws.amazon.com/amazon-s3-encryption-client/latest/developerguide/images/s3-envelope-encrypt-3.png)


**Combining the strengths of multiple algorithms**  
To encrypt your object, by default, the Amazon S3 Encryption Client uses a sophisticated algorithm suite with AES-GCM symmetric encryption. To encrypt the data key, you can specify a symmetric or asymmetric encryption algorithm appropriate to your wrapping key.  
In general, symmetric key encryption algorithms are faster and produce smaller ciphertexts than asymmetric or *public key encryption*. But public key algorithms provide inherent separation of roles and easier key management. To combine the strengths of each, you can encrypt your object with symmetric key encryption, and then encrypt the data key with public key encryption.

## Data key


A *data key* is an encryption key that the Amazon S3 Encryption Client uses to encrypt your object. Each data key is a byte array that conforms to the requirements for cryptographic keys. The Amazon S3 Encryption Client uses a unique data key to encrypt each object.

You don't need to specify, generate, implement, extend, protect or use data keys. The Amazon S3 Encryption Client does that work for you.

To protect your data keys, the Amazon S3 Encryption Client encrypts them under a *key-encryption key* known as a [wrapping key](#wrapping-key). When you call [https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html), the Amazon S3 Encryption Client uses your plaintext data key to encrypt your object, then removes it from memory as soon as possible. The Amazon S3 Encryption Client encrypts the data key with the wrapping key you provide. Then the Amazon S3 Encryption Client stores the encrypted data key with the encrypted object that the `PutObject` request uploads to Amazon S3. For more information, see [ How the Amazon S3 Encryption Client works](how-it-works.md).

## Wrapping key


A *wrapping key* is a key-encryption key that the Amazon S3 Encryption Client uses to encrypt the [data key](#data-key) that encrypts your object. You specify the wrapping key that is used to protect your data keys when you instantiate your Amazon S3 Encryption Client. Version 3.*x* of the Amazon S3 Encryption Client uses the wrapping key you specify and one of the [fully supported wrapping algorithms](encryption-algorithms.md#v3-algorithms) to encrypt and decrypt data keys.

![\[Wrapping key encrypts data key\]](http://docs.aws.amazon.com/amazon-s3-encryption-client/latest/developerguide/images/wrapping-key-2.png)


The Amazon S3 Encryption Client supports several commonly used wrapping keys, such as symmetric [AWS KMS keys](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys), Raw AES-GCM (Advanced Encryption Standard/Galois Counter Mode) keys, and Raw RSA keys.

**Note**  
Version 3.*x* of the Amazon S3 Encryption Client for Go does not support Raw AES-GCM or Raw RSA wrapping keys.

When you use envelope encryption, you need to protect your wrapping keys from unauthorized access. You can do this in any of the following ways:
+ Use a web service designed for this purpose, such as [AWS Key Management Service (AWS KMS)](https://aws.amazon.com/kms/).
+ Use a [hardware security module (HSM)](https://en.wikipedia.org/wiki/Hardware_security_module) such as those offered by [AWS CloudHSM](https://aws.amazon.com/cloudhsm/).
+ Use other key management tools and services.

If you don't have a key management system, we recommend AWS KMS. The Amazon S3 Encryption Client integrates with AWS KMS to help you protect and use your wrapping keys.

## Keyrings


To specify the wrapping keys you use for encryption and decryption, you use a keyring You can use the keyrings that the Amazon S3 Encryption Client provides or design your own implementations. The Amazon S3 Encryption Client provides keyrings that are compatible with each other subject to language constraints.

A *keyring* generates, encrypts, and decrypts data keys. When you define a keyring, you can specify the [wrapping keys](#wrapping-key) that encrypt your data keys. Most keyrings specify at least one wrapping key or a service that provides and protects wrapping keys. You can also define a keyring with no wrapping keys or a more complex keyring with additional configuration options. 

For details about specifying wrapping keys, see the examples topic of your [programming language](programming-languages.md).

## Supported encryption algorithms


An *algorithm suite* is a collection of cryptographic algorithms and related values. Cryptographic systems use the algorithm implementation to generate the ciphertext message.

To encrypt each Amazon S3 object, the Amazon S3 Encryption Client uses a unique 256-bit symmetric data encryption key and an Advanced Encryption Standard (AES) with Galois/Counter Mode (GCM) algorithm suite. This algorithm suite uses AES-GCM for authenticated encryption with a 12-byte initialization vector, and a 16-byte AES-GCM authentication tag. It does not support a key derivation function.

For information on legacy encryption algorithms, see [Supported encryption algorithms](encryption-algorithms.md).

## Cryptographic materials manager


The cryptographic materials manager (CMM) assembles the cryptographic materials that are used to encrypt and decrypt data. The *cryptographic materials* include plaintext and encrypted data keys, and an optional message signing key. You never interact with the CMM directly. The encryption and decryption methods handle it for you.

You can use the default CMM that the Amazon S3 Encryption Client provides or write a custom CMM. You can specify a CMM, but it's not required. When you specify a keyring, the Amazon S3 Encryption Client creates a default CMM for you. The default CMM gets the encryption or decryption materials from the keyring that you specify. This might involve a call to a cryptographic service, such as [AWS Key Management Service](https://docs.aws.amazon.com/kms/latest/developerguide/)(AWS KMS).

Because the CMM acts as a liaison between the Amazon S3 Encryption Client and a keyring, it is an ideal point for customization and extension, such as support for policy enforcement and caching.

## Encryption context


If you use a symmetric AWS KMS key as your wrapping key, you can include an encryption context in all requests to encrypt data. Using an encryption context is optional, but it is a cryptographic best practice that we recommend.

An *encryption context* is a set of name-value pairs that contain arbitrary, non-secret additional authenticated data. The encryption context can contain any data you choose, but it typically consists of data that is useful in logging and tracking, such as data about the file type, purpose, or ownership. When you encrypt data, the encryption context is cryptographically bound to the encrypted data so that the same encryption context is required to decrypt the data. The Amazon S3 Encryption Client stores the encryption context in plaintext in the metadata of the encrypted object that it uploads to Amazon S3. The Amazon S3 Encryption Client also uses the encryption context to provide additional authenticated data (AAD) in your AWS KMS calls.

**Note**  
We strongly recommend using only US-ASCII characters in your encryption contexts. Including non-US-ASCII characters can result in availability and compatibility errors.

The following example demonstrates how to specify an encryption context in your cryptographic operations.

1. Specify a KMS key as your wrapping key by instantiating your client with the `kmsKeyId` builder parameter.

   ```
   // v4
   
   class v4KMSKeyExample {
       public static void main(String[] args) {
           S3Client v4Client = S3EncryptionClient.builderV4()
                   .kmsKeyId(kmsKeyId)
                   .build();
       }
   }
   ```

1. Use the `overrideConfiguration` builder parameter to specify the encryption context within your `PutObject` request.

   ```
   // v4
   
   class v4EncryptExample {
       public static void main(String[] args) {
           s3Client.putObject(PutObjectRequest.builder()
                           .bucket(bucket)
                           .key(objectKey)
                           .overrideConfiguration(withAdditionalConfiguration(encryptionContext))
                           .build(), RequestBody.fromString(objectContent));
       }
   }
   ```

1. Include the same encryption context in your `GetObject` request.

   ```
   // v4
     
   class v4DecryptExample {
       public static void main(String[] args) {
           ResponseBytes<GetObjectResponse> objectResponse = s3Client.getObjectAsBytes(builder -> builder
                   .bucket(bucket)
                   .key(objectKey)
                   .overrideConfiguration(withAdditionalConfiguration(encryptionContext)));
           String output = objectResponse.asUtf8String();
       }
   }
   ```

## Instruction files


An *instruction file* is a separate Amazon S3 object that stores encryption metadata for an encrypted object. When you encrypt an object using the Amazon S3 Encryption Client, the client needs to store metadata about the encryption operation, including the encrypted [data key](#data-key), the encryption algorithm used, and other cryptographic information required to decrypt the object.

The Amazon S3 Encryption Client supports two methods for storing this encryption metadata:

**Object metadata storage (default)**  
Encryption metadata is stored in the object's metadata headers. This is the most common and convenient method as all encryption information is stored with the object itself. When you retrieve the encrypted object, the Amazon S3 Encryption Client reads the encryption metadata from the object's headers and uses it to decrypt the object.

**Instruction file storage**  
Encryption metadata is stored in a separate Amazon S3 object called an instruction file. The instruction file has the same key as the encrypted object with the suffix `.instruction` appended. For example, if your encrypted object has the key `mydata.txt`, the instruction file will have the key `mydata.txt.instruction`.

**When to use each storage method:**
+ **Use object metadata storage** for most scenarios. It simplifies object management since encryption metadata travels with the object. This is the default storage method and is recommended unless you have specific requirements that necessitate instruction files.
+ **Use instruction file storage** when object metadata size is a concern or when you need to separate encryption metadata from the encrypted object. Note that using instruction files requires managing two Amazon S3 objects (the encrypted object and its instruction file) instead of one. When you delete an encrypted object that uses instruction file storage, you must also delete the instruction file separately.

## Key commitment


The Amazon S3 Encryption Client supports *key commitment* (sometimes known as *robustness*), a security property that guarantees that each ciphertext can be decrypted only to a single plaintext. To do this, key commitment guarantees that only the data key that encrypted your object will be used to decrypt it.

Most modern symmetric ciphers (including AES) encrypt a plaintext under a single secret key, such as the [unique data key](#data-key) that the Amazon S3 Encryption Client uses to encrypt each plaintext object. Decrypting this data with the same data key returns a plaintext that is identical to the original. Decrypting with a different key will usually fail. However, it's possible to decrypt a ciphertext under two different keys. In rare cases, it is feasible to find a key that can decrypt a few bytes of ciphertext into a different, but still intelligible, plaintext.

The Amazon S3 Encryption Client always encrypts each plaintext object under one unique data key. It might encrypt that data key under multiple [wrapping keys](#wrapping-key) but the wrapping keys always encrypt the same data key.

Typically, the Amazon S3 Encryption Client only supports one data key per object. However, this data key can be changed over time. Some Amazon S3 Encryption Client implementations support the use of multiple data keys for a single object when using instruction files with custom suffixes. For example, if one user decrypts the encrypted object with the default instruction file, it returns 0x0 (false) while another user decrypting with a custom instruction file for the same encrypted object gets 0x1 (true).

For objects encrypted using the default Object Metadata storage (not instruction files), it is not possible to change the encrypted data key associated with the object without changing the object. Object Metadata in S3 is immutable, so changing the metadata is equivalent to changing the object itself.

To prevent this scenario, the Amazon S3 Encryption Client supports key commitment when encrypting and decrypting. When the Amazon S3 Encryption Client encrypts an object with key commitment, it cryptographically binds the unique data key that produced the ciphertext to the *key commitment string*, a non-secret data key identifier. Then it stores the key commitment string in the metadata of the encrypted object. When it decrypts a message with key commitment, the Amazon S3 Encryption Client verifies that the data key is the one and only key for that encrypted message. If data key verification fails, the decrypt operation fails.

Support for key commitment is introduced in the latest minor versions of 3.*x* for Java, Go, .NET, 2.*x* for Ruby, PHP, and C\$1\$1. These languages can decrypt objects with key commitment, but won't encrypt with key commitment. You can use this version to fully deploy the ability to decrypt ciphertext with key commitment.

Supported languages include full support for key commitment. By default, it encrypts and decrypts only with key commitment. This is an ideal configuration for applications that don't need to decrypt ciphertext encrypted by earlier versions of the Amazon S3 Encryption Client.

Although encrypting and decrypting with key commitment is a best practice, we let you decide when it's used, and let you adjust the pace at which you adopt it. The Amazon S3 Encryption Client supports a commitment policy that sets the default algorithm suite and limits the algorithm suites that may be used. This policy determines whether your data is encrypted and decrypted with key commitment.

Key commitment results in a slightly larger (\$1 56 bytes) encrypted message and takes more time to process. If your application is very sensitive to size or performance, you might choose to opt out of key commitment. But do so only if you must.

For more information about migrating to the latest version, including their key commitment features, see the migration guide for your [programming language](programming-languages.md).

## Commitment policy


A *commitment policy* is a configuration setting that determines whether your application encrypts and decrypts with [ key commitment](#key-commitment).

Commitment policy has three values:


| Value | Encrypts with key commitment | Encrypts without key commitment | Decrypts with key commitment | Decrypts without key commitment | 
| --- | --- | --- | --- | --- | 
| ForbidEncryptAllowDecrypt | never | always | yes | yes | 
| RequireEncryptAllowDecrypt | always | never | yes | yes | 
| RequireEncryptRequireDecrypt | always | never | yes | never | 

The commitment policy setting is introduced in minor versions of supported languages. It's valid in all supported [programming languages](programming-languages.md).

**`ForbidEncryptAllowDecrypt`**  
This policy decrypts with or without key commitment, but it won't encrypt with key commitment. This value is designed to prepare all hosts running your application to decrypt with key commitment before they ever encounter a ciphertext encrypted with key commitment.

**`RequireEncryptAllowDecrypt`**  
This policy always encrypts with key commitment. It can decrypt with or without key commitment. This value lets you start encrypting with key commitment, but still decrypt ciphertexts without key commitment.

**`RequireEncryptRequireDecrypt`**  
This policy encrypts and decrypts only with key commitment. Use this value when you are certain that all of your ciphertexts are encrypted with key commitment.

The commitment policy setting determines which algorithm suites you can use. If you specify an algorithm suite that conflicts with your commitment policy, the Amazon S3 Encryption Client returns an error.

The Amazon S3 Encryption Client supports encryption using key commitment in major version 4.x for Java, Go, and .NET, and major version 3.x for Ruby, PHP, and C\$1\$1.

For help setting your commitment policy, see the migration guide for your [programming language](programming-languages.md).

# How the Amazon S3 Encryption Client works
How it works

**Note**  
This documentation describes the Amazon S3 Encryption Client version 3.*x* and newer, which is an independent library. For information about previous versions of the Amazon S3 Encryption Client, see the AWS SDK Developer Guide for your programming language. 

The Amazon S3 Encryption Client is designed specifically to protect the data that you store in Amazon S3. The workflows in this section explain how the Amazon S3 Encryption Client encrypts and decrypts your objects.

The Amazon S3 Encryption Client uses envelope encryption to protect your objects. It encrypts each Amazon S3 object under a unique data encryption key. Then it encrypts the data encryption key with a wrapping key that you specify.

Need help with the terminology we use in the Amazon S3 Encryption Client? See [Amazon S3 Encryption Client concepts](concepts.md).

## Encrypt and decrypt with the Amazon S3 Encryption Client
Encrypt and decrypt

The Amazon S3 Encryption Client works as an intermediary between you and Amazon S3 by encrypting your object as you upload it, and decrypting your object as you download it. The following walkthrough specifies an RSA key pair as the wrapping key. For detailed code examples, see the *Examples* topic of your preferred [programming language](programming-languages.md).

1. Specify your wrapping key and create a [keyring](concepts.md#keyring) when you instantiate your client.

1. Encrypt your plaintext object by calling [https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html).

   1. The Amazon S3 Encryption Client provides the encryption materials: one plaintext data key and one copy of that data key encrypted by your wrapping key.

   1. The Amazon S3 Encryption Client uses the plaintext data key to encrypt your object, and then discards the plaintext data key.

   1. The Amazon S3 Encryption Client uploads the encrypted data key and the encrypted object to Amazon S3 as part of the `PutObject` call.

1. Decrypt your encrypted object by calling [https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html).

   1. The Amazon S3 Encryption Client uses your wrapping key to decrypt the encrypted data key.

   1. The Amazon S3 Encryption Client uses the plaintext data key to decrypt the object, discards the plaintext data key, and returns the plaintext object as part of the `GetObject` call.

# Client-side and server-side encryption


**Note**  
This documentation describes the Amazon S3 Encryption Client version 3.*x* and newer, which is an independent library. For information about previous versions of the Amazon S3 Encryption Client, see the AWS SDK Developer Guide for your programming language. 

The Amazon S3 Encryption Client supports *client-side encryption*, where you encrypt your objects before you send them to Amazon S3. Amazon S3 provides server-side encryption options that encrypt your objects at their destination before they are saved in Amazon S3.

The tools that you choose depend on your security requirements and the sensitivity of your data. You can use both the Amazon S3 Encryption Client and Amazon S3 server-side encryption. When you send encrypted objects to Amazon S3, Amazon S3 doesn't recognize the objects as being encrypted, it just detects typical objects.

**Server-side encryption**

Amazon S3 supports encryption at rest with three mutually exclusive [server-side encryption](https://docs.aws.amazon.com/AmazonS3/latest/userguide/serv-side-encryption.html) options. Amazon S3 encrypts your data at the object level as it writes it to disks in its data centers and decrypts it for you when you access it.

**Amazon S3 Encryption Client**

Client-side encryption provides end-to-end protection for your object, in transit and at rest, from its source to storage in Amazon S3.
+ Your data is protected in transit and at rest. It is never exposed to any third party, including AWS.
+ You choose how your cryptographic keys are protected. You specify the wrapping key used to protect the data keys that encrypt your objects.
+ Your objects are all encrypted with a unique data key. The Amazon S3 Encryption Client does not use or interact with [bucket keys](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingKMSEncryption.html#sse-kms-bucket-keys), even if you specify a KMS key as your wrapping key.