Amazon S3 Encryption Client concepts - Amazon S3 Encryption Client

Amazon S3 Encryption Client concepts

Note

This documentation describes the Amazon S3 Encryption Client version 3.x, 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.

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. 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. 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
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. When you call PutObject, 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.

Wrapping key

A wrapping key is a key-encryption key that the Amazon S3 Encryption Client uses to encrypt the 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 to encrypt and decrypt data keys.

Wrapping key encrypts data key

The Amazon S3 Encryption Client supports several commonly used wrapping keys, such as symmetric AWS KMS 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:

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 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.

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.

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(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.

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.

    // v3 class v3KMSKeyExample { public static void main(String[] args) { S3Client v3Client = S3EncryptionClient.builder() .kmsKeyId(kmsKeyId) .build(); } }
  2. Use the overrideConfiguration builder parameter to specify the encryption context within your PutObject request.

    // v3 class v3EncryptExample { public static void main(String[] args) { s3Client.putObject(PutObjectRequest.builder() .bucket(bucket) .key(objectKey) .overrideConfiguration(withAdditionalConfiguration(encryptionContext)), .build(), RequestBody.fromString(objectContent)); } }
  3. Include the same encryption context in your GetObject request.

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