

# What is the AWS Encryption SDK?
<a name="introduction"></a>

The AWS Encryption SDK is a client-side encryption library designed to make it easy for everyone to encrypt and decrypt data using industry standards and best practices. It enables you to focus on the core functionality of your application, rather than on how to best encrypt and decrypt your data. The AWS Encryption SDK is provided free of charge under the Apache 2.0 license.

The AWS Encryption SDK answers questions like the following for you:
+ Which encryption algorithm should I use?
+ How, or in which mode, should I use that algorithm?
+ How do I generate the encryption key?
+ How do I protect the encryption key, and where should I store it?
+ How can I make my encrypted data portable?
+ How do I ensure that the intended recipient can read my encrypted data?
+ How can I ensure my encrypted data is not modified between the time it is written and when it is read?
+ How do I use the data keys that AWS KMS returns?

With the AWS Encryption SDK, you define a [master key provider](concepts.md#master-key-provider) or a [keyring](concepts.md#keyring) that determines which wrapping keys you use to protect your data. Then you encrypt and decrypt your data using straightforward methods provided by the AWS Encryption SDK. The AWS Encryption SDK does the rest.

Without the AWS Encryption SDK, you might spend more effort on building an encryption solution than on the core functionality of your application. The AWS Encryption SDK answers these questions by providing the following things.

**A default implementation that adheres to cryptography best practices**  
By default, the AWS Encryption SDK generates a unique data key for each data object that it encrypts. This follows the cryptography best practice of using unique data keys for each encryption operation.  
The AWS Encryption SDK encrypts your data using a secure, authenticated, symmetric key algorithm. For more information, see [Supported algorithm suites in the AWS Encryption SDK](supported-algorithms.md).

**A framework for protecting data keys with wrapping keys**  
The AWS Encryption SDK protects the data keys that encrypt your data by encrypting them under one or more wrapping keys. By providing a framework to encrypt data keys with more than one wrapping key, the AWS Encryption SDK helps make your encrypted data portable.   
For example, encrypt data under an AWS KMS key in AWS KMS and a key from your on-premises HSM. You can use either of the wrapping keys to decrypt the data, in case one is unavailable or the caller doesn't have permission to use both keys.

**A formatted message that stores encrypted data keys with the encrypted data**  
The AWS Encryption SDK stores the encrypted data and encrypted data key together in an [encrypted message](concepts.md#message) that uses a defined data format. This means you don't need to keep track of or protect the data keys that encrypt your data because the AWS Encryption SDK does it for you.

Some language implementations of the AWS Encryption SDK require an AWS SDK, but the AWS Encryption SDK doesn't require an AWS account and it doesn't depend on any AWS service. You need an AWS account only if you choose to use [AWS KMS keys](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#kms-keys) to protect your data.

## Developed in open-source repositories
<a name="esdk-repos"></a>

The AWS Encryption SDK is developed in open-source repositories on GitHub. You can use these repositories to view the code, read and submit issues, and find information that is specific to your language implementation.
+ AWS Encryption SDK for C — [aws-encryption-sdk-c](https://github.com/aws/aws-encryption-sdk-c/)
+ AWS Encryption SDK for .NET — [.NET](https://github.com/aws/aws-encryption-sdk/tree/mainline/AwsEncryptionSDK/runtimes/net/) directory of the `aws-encryption-sdk` repository.
+ AWS Encryption CLI — [aws-encryption-sdk-cli](https://github.com/aws/aws-encryption-sdk-cli/)
+ AWS Encryption SDK for Java — [aws-encryption-sdk-java](https://github.com/aws/aws-encryption-sdk-java/)
+ AWS Encryption SDK for JavaScript — [aws-encryption-sdk-javascript](https://github.com/aws/aws-encryption-sdk-javascript/)
+ AWS Encryption SDK for Python — [aws-encryption-sdk-python](https://github.com/aws/aws-encryption-sdk-python/)
+ AWS Encryption SDK for Rust — [Rust](https://github.com/aws/aws-encryption-sdk-dafny/tree/mainline/AwsEncryptionSDK/runtimes/rust/) directory of the `aws-encryption-sdk` repository.
+ AWS Encryption SDK for Go — [Go](https://github.com/aws/aws-encryption-sdk/tree/mainline/releases/go/encryption-sdk/) directory of the `aws-encryption-sdk` repository

## Compatibility with encryption libraries and services
<a name="intro-compatibility"></a>

The AWS Encryption SDK is supported in several [programming languages](programming-languages.md). All language implementations are interoperable. You can encrypt with one language implementation and decrypt with another. Interoperability might be subject to language constraints. If so, these constraints are described in the topic about the language implementation. Also, when encrypting and decrypting, you must use compatible keyrings, or master keys and master key providers. For details, see [Keyring compatibility](choose-keyring.md#keyring-compatibility).

However, the AWS Encryption SDK cannot interoperate with other libraries. Because each library returns encrypted data in a different format, you cannot encrypt with one library and decrypt with another.

**DynamoDB Encryption Client and Amazon S3 client-side encryption**  <a name="ESDK-DDBEC"></a>
The AWS Encryption SDK cannot decrypt data encrypted by the [DynamoDB Encryption Client](https://docs.aws.amazon.com/dynamodb-encryption-client/latest/devguide/) or [Amazon S3 client-side encryption](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingClientSideEncryption.html). These libraries cannot decrypt the [encrypted message](concepts.md#message) the AWS Encryption SDK returns. 

**AWS Key Management Service (AWS KMS)**  <a name="ESDK-KMS"></a>
The AWS Encryption SDK can use [AWS KMS keys](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys) and [data keys](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#data-keys) to protect your data, including multi-Region KMS keys. For example, you can configure the AWS Encryption SDK to encrypt your data under one or more AWS KMS keys in your AWS account. However, you must use the AWS Encryption SDK to decrypt that data.   
The AWS Encryption SDK cannot decrypt the ciphertext that the AWS KMS [Encrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_Encrypt.html) or [ReEncrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_ReEncrypt.html) operations return. Similarly, the AWS KMS [Decrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.html) operation cannot decrypt the [encrypted message](concepts.md#message) the AWS Encryption SDK returns.  
The AWS Encryption SDK supports only [symmetric encryption KMS keys](https://docs.aws.amazon.com/kms/latest/developerguide/symm-asymm-concepts.html#symmetric-cmks). You cannot use an [asymmetric KMS key](https://docs.aws.amazon.com/kms/latest/developerguide/symm-asymm-concepts.html#asymmetric-cmks) for encryption or signing in the AWS Encryption SDK. The AWS Encryption SDK generates its own ECDSA signing keys for [algorithm suites](supported-algorithms.md) that sign messages.

## Support and maintenance
<a name="support"></a>

The AWS Encryption SDK uses the same [maintenance policy](https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html) that the AWS SDK and Tools use, including its versioning and life-cycle phases. As a [best practice](best-practices.md), we recommend that you use the latest available version of the AWS Encryption SDK for your programming language, and upgrade as new versions are released. When a version requires significant changes, such as the upgrade from AWS Encryption SDK versions earlier than 1.7.*x* to versions 2.0.*x* and later, we provide [detailed instructions](migration.md) to help you.

Each programming language implementation of the AWS Encryption SDK is developed in a separate open-source GitHub repository. The life-cycle and support phase of each version is likely to vary among repositories. For example, a given version of the AWS Encryption SDK might be in the general availability (full support) phase in one programming language, but the end-of-support phase in a different programming language. We recommend that you use a fully supported version whenever possible and avoid versions that are no longer supported.

To find the life-cycle phase of AWS Encryption SDK versions for your programming language, see the `SUPPORT_POLICY.rst` file in each AWS Encryption SDK repository.
+ AWS Encryption SDK for C — [SUPPORT\$1POLICY.rst](https://github.com/aws/aws-encryption-sdk-c/blob/master/SUPPORT_POLICY.rst)
+ AWS Encryption SDK for .NET — [SUPPORT\$1POLICY.rst](https://github.com/aws/aws-encryption-sdk-dafny/blob/mainline/SUPPORT_POLICY.rst)
+ AWS Encryption CLI — [SUPPORT\$1POLICY.rst](https://github.com/aws/aws-encryption-sdk-cli/blob/master/SUPPORT_POLICY.rst)
+ AWS Encryption SDK for Java — [SUPPORT\$1POLICY.rst](https://github.com/aws/aws-encryption-sdk-java/blob/master/SUPPORT_POLICY.rst)
+ AWS Encryption SDK for JavaScript — [SUPPORT\$1POLICY.rst](https://github.com/aws/aws-encryption-sdk-javascript/blob/master/SUPPORT_POLICY.rst)
+ AWS Encryption SDK for Python — [SUPPORT\$1POLICY.rst](https://github.com/aws/aws-encryption-sdk-python/blob/master/SUPPORT_POLICY.rst)

For more information, see [Versions of the AWS Encryption SDK](about-versions.md) and [AWS SDKs and Tools maintenance policy](https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html) in the AWS SDKs and Tools Reference Guide.

## Learning more
<a name="intro-see-also"></a>

For more information about the AWS Encryption SDK and client-side encryption, try these sources.
+ For help with the terms and concepts used in this SDK, see [Concepts in the AWS Encryption SDK](concepts.md).
+ For best practice guidelines, see [Best practices for the AWS Encryption SDK](best-practices.md).
+ For information about how this SDK works, see [How the SDK works](how-it-works.md).
+ For examples that show how to configure options in the AWS Encryption SDK, see [Configuring the AWS Encryption SDK](configure.md).
+ For detailed technical information, see the [AWS Encryption SDK reference](reference.md).
+ For the technical specification for the AWS Encryption SDK, see the [AWS Encryption SDK Specification](https://github.com/awslabs/aws-encryption-sdk-specification/) in GitHub.
+ For answers to your questions about using the AWS Encryption SDK, read and post on the [AWS Crypto Tools Discussion Forum](https://forums.aws.amazon.com/forum.jspa?forumID=302).

For information about implementations of the AWS Encryption SDK in different programming languages.
+ **C**: See [AWS Encryption SDK for C](c-language.md), the AWS Encryption SDK [C documentation](https://aws.github.io/aws-encryption-sdk-c/html/), and the [aws-encryption-sdk-c](https://github.com/aws/aws-encryption-sdk-c/) repository on GitHub.
+ **C\$1/.NET**: See [AWS Encryption SDK for .NET](dot-net.md) and the [aws-encryption-sdk-net](https://github.com/aws/aws-encryption-sdk/tree/mainline/AwsEncryptionSDK/runtimes/net/) directory of the `aws-encryption-sdk` repository on GitHub.
+ **Command Line Interface**: See [AWS Encryption SDK command line interface](crypto-cli.md), [Read the Docs](https://aws-encryption-sdk-cli.readthedocs.io/en/latest/) for the AWS Encryption CLI, and the [aws-encryption-sdk-cli](https://github.com/aws/aws-encryption-sdk-cli/) repository on GitHub.
+ **Java**: See [AWS Encryption SDK for Java](java.md), the AWS Encryption SDK [Javadoc](https://aws.github.io/aws-encryption-sdk-java/), and the [aws-encryption-sdk-java](https://github.com/aws/aws-encryption-sdk-java/) repository on GitHub.

  **JavaScript**: See [AWS Encryption SDK for JavaScript](javascript.md) and the [aws-encryption-sdk-javascript](https://github.com/aws/aws-encryption-sdk-javascript/) repository on GitHub. 
+ **Python**: See [AWS Encryption SDK for Python](python.md), the AWS Encryption SDK [Python documentation](https://aws-encryption-sdk-python.readthedocs.io/en/latest/), and the [aws-encryption-sdk-python](https://github.com/aws/aws-encryption-sdk-python/) repository on GitHub.

## Sending feedback
<a name="report-issues"></a>

We welcome your feedback\$1 If you have a question or comment, or an issue to report, please use the following resources.
+ If you discover a potential security vulnerability in the AWS Encryption SDK, please [notify AWS security](https://aws.amazon.com/security/vulnerability-reporting/). Do not create a public GitHub issue.
+ To provide feedback on the AWS Encryption SDK, file an issue in the GitHub repository for the programming language you are using. 
+ To provide feedback on this documentation, use the **Feedback** links on this page. You can also file an issue or contribute to [aws-encryption-sdk-docs](https://github.com/awsdocs/aws-encryption-sdk-docs), the open-source repository for this documentation on GitHub.

# Concepts in the AWS Encryption SDK
<a name="concepts"></a>

This section introduces the concepts used in the AWS Encryption SDK, and provides a glossary and reference. It's designed to help you understand how the AWS Encryption SDK works and the terms we use to describe it.

Need help? 
+ Learn how the AWS Encryption SDK uses [envelope encryption](#envelope-encryption) to protect your data.
+ Learn about the elements of envelope encryption: the [data keys](#DEK) that protect your data and the [wrapping keys](#master-key) that protect your data keys. 
+ Learn about the [keyrings](#keyring) and [master key providers](#master-key-provider) that determine which wrapping keys you use.
+ Learn about the [encryption context](#encryption-context) that adds integrity to your encryption process. It's optional, but it's a best practice that we recommend.
+ Learn about the [encrypted message](#message) that the encryption methods return. 
+ Then you're ready to use the AWS Encryption SDK in your preferred [programming language](programming-languages.md).

**Topics**
+ [

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

## Data key
](#DEK)
+ [

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

## Keyrings and master key providers
](#keyring)
+ [

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

## Encrypted message
](#message)
+ [

## Algorithm suite
](#crypto-algorithm)
+ [

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

## Symmetric and asymmetric encryption
](#symmetric-key-encryption)
+ [

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

## Commitment policy
](#commitment-policy)
+ [

## Digital signatures
](#digital-sigs)

## Envelope encryption
<a name="envelope-encryption"></a>

The security of your encrypted data 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](#master-key). The practice of using a wrapping key to encrypt data keys is known as *envelope encryption*.

**Protecting data keys**  
The AWS Encryption SDK encrypts each message 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 data in the encrypted message that it returns.  
To specify your wrapping key, you use a [keyring](#keyring) or [master key provider](#master-key-provider).  

![\[Envelope encryption with the AWS Encryption SDK\]](http://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/images/envelope-encryption-70.png)


**Encrypting the same data under multiple wrapping keys**  
You can encrypt the data key under multiple wrapping keys. You might want to provide different wrapping keys for different users, or wrapping keys of different types, or in different locations. Each of the wrapping keys encrypts the same data key. The AWS Encryption SDK stores all of the encrypted data keys with the encrypted data in the encrypted message.   
To decrypt the data, you need to provide a wrapping key that can decrypt one of the encrypted data keys.  

![\[Each wrapping key encrypts the same data key, resulting in one encrypted data key for each wrapping key\]](http://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/images/multiple-wrapping-keys-70.png)


**Combining the strengths of multiple algorithms**  
To encrypt your data, by default, the AWS Encryption SDK uses a sophisticated [algorithm suite](supported-algorithms.md) with AES-GCM symmetric encryption, a key derivation function (HKDF), and signing. To encrypt the data key, you can specify a [symmetric or asymmetric encryption algorithm](#symmetric-key-encryption) 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 data with symmetric key encryption, and then encrypt the data key with public key encryption.

## Data key
<a name="DEK"></a>

A *data key* is an encryption key that the AWS Encryption SDK uses to encrypt your data. Each data key is a byte array that conforms to the requirements for cryptographic keys. Unless you're using [data key caching](data-key-caching.md), the AWS Encryption SDK uses a unique data key to encrypt each message.

You don't need to specify, generate, implement, extend, protect or use data keys. The AWS Encryption SDK does that work for you when you call the encrypt and decrypt operations. 

To protect your data keys, the AWS Encryption SDK encrypts them under one or more *key-encryption keys* known as [wrapping keys](#master-key) or master keys. After the AWS Encryption SDK uses your plaintext data keys to encrypt your data, it removes them from memory as soon as possible. Then it stores the encrypted data keys with the encrypted data in the [encrypted message](#message) that the encrypt operations return. For details, see [How the AWS Encryption SDK works](how-it-works.md).

**Tip**  
In the AWS Encryption SDK, we distinguish *data keys* from *data encryption keys*. Several of the supported [algorithm suites](#crypto-algorithm), including the default suite, use a [key derivation function](https://en.wikipedia.org/wiki/Key_derivation_function) that prevents the data key from hitting its cryptographic limits. The key derivation function takes the data key as input and returns a data encryption key that is actually used to encrypt the data. For this reason, we often say that data is encrypted "under" a data key rather than "by" the data key.

Each encrypted data key includes metadata, including the identifier of the wrapping key that encrypted it. This metadata makes it easier for the AWS Encryption SDK to identify valid wrapping keys when decrypting.

## Wrapping key
<a name="master-key"></a>

A *wrapping key* is a key-encryption key that the AWS Encryption SDK uses to encrypt the [data key](#DEK) that encrypts your data. Each plaintext data key can be encrypted under one or more wrapping keys. You determine which wrapping keys are used to protect your data when you configure a [keyring](#keyring) or [master key provider](#master-key-provider).

**Note**  
*Wrapping key* refers to the keys in a keyring or master key provider. *Master key* is typically associated with the `MasterKey` class that you instantiate when you use a master key provider.

The AWS Encryption SDK supports several commonly used wrapping keys, such as AWS Key Management Service (AWS KMS) symmetric [AWS KMS keys](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys) (including [multi-Region KMS keys](configure.md#config-mrks)), raw AES-GCM (Advanced Encryption Standard/Galois Counter Mode) keys, and raw RSA keys. You can also extend or implement your own 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 AWS Encryption SDK integrates with AWS KMS to help you protect and use your wrapping keys. However, the AWS Encryption SDK does not require AWS or any AWS service.

## Keyrings and master key providers
<a name="keyring"></a>

To specify the wrapping keys you use for encryption and decryption, you use a keyring or a master key provider. You can use the keyrings and master key providers that the AWS Encryption SDK provides or design your own implementations. The AWS Encryption SDK provides keyrings and master key providers that are compatible with each other subject to language constraints. For details, see [Keyring compatibility](choose-keyring.md#keyring-compatibility). 

A *keyring* generates, encrypts, and decrypts data keys. When you define a keyring, you can specify the [wrapping keys](#master-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 help choosing and using the keyrings that the AWS Encryption SDK defines, see [Keyrings](choose-keyring.md). 

Keyrings are supported in the following programming languages:
+ AWS Encryption SDK for C
+ AWS Encryption SDK for JavaScript
+ AWS Encryption SDK for .NET
+ Version 3.*x* of the AWS Encryption SDK for Java
+ Version 4.*x* of the AWS Encryption SDK for Python, when used with the optional [Cryptographic Material Providers Library](https://github.com/aws/aws-cryptographic-material-providers-library) (MPL) dependency.
+ Version 1.*x* of the AWS Encryption SDK for Rust
+ Version 0.1.*x* or later of the AWS Encryption SDK for Go

A *master key provider* is an alternative to a keyring. The master key provider returns the wrapping keys (or master keys) you specify. Each master key is associated with one master key provider, but a master key provider typically provides multiple master keys. Master key providers are supported in Java, Python, and the AWS Encryption CLI. 

You must specify a keyring (or master key provider) for encryption. You can specify the same keyring (or master key provider), or a different one, for decryption. When encrypting, the AWS Encryption SDK uses all of the wrapping keys you specify to encrypt the data key. When decrypting, the AWS Encryption SDK uses only the wrapping keys you specify to decrypt an encrypted data key. Specifying wrapping keys for decryption is optional, but it's a AWS Encryption SDK [best practice](best-practices.md). 

For details about specifying wrapping keys, see [Selecting wrapping keys](configure.md#config-keys). 

## Encryption context
<a name="encryption-context"></a>

To improve the security of your cryptographic operations, 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 AWS Encryption SDK includes the encryption context in plaintext in the header of the [encrypted message](#message) that it returns.

The encryption context that the AWS Encryption SDK uses consists of the encryption context that you specify and a public key pair that the [cryptographic materials manager](#crypt-materials-manager) (CMM) adds. Specifically, whenever you use an [encryption algorithm with signing](algorithms-reference.md), the CMM adds a name-value pair to the encryption context that consists of a reserved name, `aws-crypto-public-key`, and a value that represents the public verification key. The `aws-crypto-public-key` name in the encryption context is reserved by the AWS Encryption SDK and cannot be used as a name in any other pair in the encryption context. For details, see [AAD](message-format.md#header-aad) in the *Message Format Reference*.

The following example encryption context consists of two encryption context pairs specified in the request and the public key pair that the CMM adds.

```
"Purpose"="Test", "Department"="IT", aws-crypto-public-key=<public key>
```

To decrypt the data, you pass in the encrypted message. Because the AWS Encryption SDK can extract the encryption context from the encrypted message header, you are not required to provide the encryption context separately. However, the encryption context can help you to confirm that you are decrypting the correct encrypted message. 
+ In the [AWS Encryption SDK Command Line Interface](crypto-cli.md) (CLI), if you provide an encryption context in a decrypt command, the CLI verifies that the values are present in the encryption context of the encrypted message before it returns the plaintext data. 
+ In other programming language implementations, the decrypt response includes the encryption context and the plaintext data. The decrypt function in your application should always verify that the encryption context in the decrypt response includes the encryption context in the encrypt request (or a subset) before it returns the plaintext data.

**Note**  
The following versions support the [required encryption context CMM](configure.md#config-required-encryption-context-cmm), which you can use to require an encryption context in all encrypt requests.  
Version 3.*x* of the AWS Encryption SDK for Java
Version 4.*x* and later of the AWS Encryption SDK for .NET
Version 4.*x* of the AWS Encryption SDK for Python, when used with the optional [Cryptographic Material Providers Library](https://github.com/aws/aws-cryptographic-material-providers-library) (MPL) dependency.
Version 1.*x* of the AWS Encryption SDK for Rust
Version 0.1.*x* or later of the AWS Encryption SDK for Go

When choosing an encryption context, remember that it is not a secret. The encryption context is displayed in plaintext in the header of the [encrypted message](#message) that the AWS Encryption SDK returns. If you are using AWS Key Management Service, the encryption context also might appear in plaintext in audit records and logs, such as AWS CloudTrail.

For examples of submitting and verifying an encryption context in your code, see the examples for your preferred [programming language](programming-languages.md).

## Encrypted message
<a name="message"></a>

When you encrypt data with the AWS Encryption SDK, it returns an encrypted message.

An *encrypted message* is a portable [formatted data structure](message-format.md) that includes the encrypted data along with encrypted copies of the data keys, the algorithm ID, and, optionally, an [encryption context](#encryption-context) and a [digital signature](#digital-sigs). Encrypt operations in the AWS Encryption SDK return an encrypted message and decrypt operations take an encrypted message as input. 

Combining the encrypted data and its encrypted data keys streamlines the decryption operation and frees you from having to store and manage encrypted data keys independently of the data that they encrypt.

For technical information about the encrypted message, see [Encrypted Message Format](message-format.md).

## Algorithm suite
<a name="crypto-algorithm"></a>

The AWS Encryption SDK uses an algorithm suite to encrypt and sign the data in the [encrypted message](#message) that the encrypt and decrypt operations return. The AWS Encryption SDK supports several [algorithm suites](supported-algorithms.md). All of the supported suites use Advanced Encryption Standard (AES) as the primary algorithm, and combine it with other algorithms and values. 

The AWS Encryption SDK establishes a recommended algorithm suite as the default for all encryption operations. The default might change as standards and best practices improve. You can specify an alternate algorithm suite in requests to encrypt data or when creating a [cryptographic materials manager (CMM)](#crypt-materials-manager), but unless an alternate is required for your situation, it is best to use the default. The current default is AES-GCM with an HMAC-based extract-and-expand [key derivation function](https://en.wikipedia.org/wiki/HKDF) ([HKDF](https://en.wikipedia.org/wiki/HKDF)), [key commitment](#key-commitment), an [Elliptic Curve Digital Signature Algorithm (ECDSA)](#digital-sigs) signature, and a 256-bit encryption key. 

If your application requires high performance and the users who are encrypting data and those who are decrypting data are equally trusted, you might consider specifying an algorithm suite without a digital signature. However, we strongly recommend an algorithm suite that includes key commitment and a key derivation function. Algorithm suites without these features are supported only for backward compatibility.

## Cryptographic materials manager
<a name="crypt-materials-manager"></a>

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 or the [caching CMM](data-key-caching.md) that the AWS Encryption SDK provides, or write a custom CMM. And you can specify a CMM, but it's not required. When you specify a keyring or master key provider, the AWS Encryption SDK creates a default CMM for you. The default CMM gets the encryption or decryption materials from the keyring or master key provider 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 AWS Encryption SDK and a keyring (or master key provider), it is an ideal point for customization and extension, such as support for policy enforcement and caching. The AWS Encryption SDK provides a caching CMM to support [data key caching.](data-key-caching.md) 

## Symmetric and asymmetric encryption
<a name="symmetric-key-encryption"></a>

*Symmetric encryption* uses the same key to encrypt and decrypt data. 

*Asymmetric encryption* uses a mathematically related data key pair. One key in the pair encrypts the data; only the other key in the pair can decrypt the data.

The AWS Encryption SDK uses [envelope encryption](#envelope-encryption). It encrypts your data with a symmetric data key. It encrypts the symmetric data key with one or more symmetric or asymmetric wrapping keys. It returns an [encrypted message](#message) that includes the encrypted data and at least one encrypted copy of the data key. 

**Encrypting your data (symmetric encryption)**  
To encrypt your data, the AWS Encryption SDK uses a symmetric [data key](#DEK) and an [algorithm suite](#crypto-algorithm) that includes a symmetric encryption algorithm. To decrypt the data, the AWS Encryption SDK uses the same data key and the same algorithm suite.

**Encrypting your data key (symmetric or asymmetric encryption)**  
The [keyring](#keyring) or [master key provider](#master-key-provider) that you supply to an encrypt and decrypt operation determines how the symmetric data key is encrypted and decrypted. You can choose a keyring or master key provider that uses symmetric encryption, such as a AWS KMS keyring, or one that uses asymmetric encryption, such as a raw RSA keyring or `JceMasterKey`.

## Key commitment
<a name="key-commitment"></a>

The AWS Encryption SDK 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 message will be used to decrypt it. Encrypting and decrypting with key commitment is an [AWS Encryption SDK best practice](best-practices.md).

Most modern symmetric ciphers (including AES) encrypt a plaintext under a single secret key, such as the [unique data key](#DEK) that the AWS Encryption SDK uses to encrypt each plaintext message. 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 AWS Encryption SDK always encrypts each plaintext message under one unique data key. It might encrypt that data key under multiple wrapping keys (or master keys), but the wrapping keys always encrypt the same data key. Nonetheless, a sophisticated, manually crafted [encrypted message](#message) might actually contain different data keys, each encrypted by a different wrapping key. For example, if one user decrypts the encrypted message it returns 0x0 (false) while another user decrypting the same encrypted message gets 0x1 (true).

To prevent this scenario, the AWS Encryption SDK supports key commitment when encrypting and decrypting. When the AWS Encryption SDK encrypts a message 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 key commitment string in the metadata of the encrypted message. When it decrypts a message with key commitment, the AWS Encryption SDK 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 version 1.7.*x*, which can decrypt messages 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. Version 2.0.*x* includes 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 AWS Encryption SDK. 

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. Beginning in version 1.7.*x*, AWS Encryption SDK supports a [commitment policy](#commitment-policy) that sets the [default algorithm suite](supported-algorithms.md) 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 30 bytes) encrypted message](message-format.md) 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 versions 1.7.*x* and 2.0.*x*, including their key commitment features, see [Migrating your AWS Encryption SDK](migration.md). For technical information about key commitment, see [AWS Encryption SDK algorithms reference](algorithms-reference.md) and [AWS Encryption SDK message format reference](message-format.md).

## Commitment policy
<a name="commitment-policy"></a>

A *commitment policy* is a configuration setting that determines whether your application encrypts and decrypts with [key commitment](#key-commitment). Encrypting and decrypting with key commitment is an [AWS Encryption SDK best practice](best-practices.md). 

Commitment policy has three values.

**Note**  
You might have to scroll horizontally or vertically to see the entire table.


**Commitment policy values**  

| Value | Encrypts with key commitment | Encrypts without key commitment | Decrypts with key commitment | Decrypts without key commitment | 
| --- | --- | --- | --- | --- | 
| ForbidEncryptAllowDecrypt | ![\[Red circle with white X inside, indicating prohibition or cancellation.\]](http://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/images/icon-no.png)  | ![\[Green checkmark icon indicating approval or confirmation.\]](http://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/images/icon-yes.png)  | ![\[Green checkmark icon indicating approval or confirmation.\]](http://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/images/icon-yes.png) | ![\[Green checkmark icon indicating approval or confirmation.\]](http://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/images/icon-yes.png) | 
| RequireEncryptAllowDecrypt | ![\[Green checkmark icon indicating approval or confirmation.\]](http://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/images/icon-yes.png) | ![\[Red circle with white X inside, indicating prohibition or cancellation.\]](http://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/images/icon-no.png) | ![\[Green checkmark icon indicating approval or confirmation.\]](http://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/images/icon-yes.png) | ![\[Green checkmark icon indicating approval or confirmation.\]](http://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/images/icon-yes.png) | 
| RequireEncryptRequireDecrypt | ![\[Green checkmark icon indicating approval or confirmation.\]](http://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/images/icon-yes.png) | ![\[Red circle with white X inside, indicating prohibition or cancellation.\]](http://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/images/icon-no.png) | ![\[Green checkmark icon indicating approval or confirmation.\]](http://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/images/icon-yes.png) | ![\[Red circle with white X inside, indicating prohibition or cancellation.\]](http://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/images/icon-no.png) | 

The commitment policy setting is introduced in AWS Encryption SDK version 1.7.*x*. It's valid in all supported [programming languages](programming-languages.md).
+ `ForbidEncryptAllowDecrypt` decrypts with or without key commitment, but it won't encrypt with key commitment. This value, introduced in version 1.7.*x*, 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` always encrypts with key commitment. It can decrypt with or without key commitment. This value, introduced in version 2.0.*x*, lets you start encrypting with key commitment, but still decrypt legacy ciphertexts without key commitment.
+ `RequireEncryptRequireDecrypt` encrypts and decrypts only with key commitment. This value is the default for version 2.0.*x*. 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. Beginning in version 1.7.*x*, the AWS Encryption SDK supports [algorithm suites](supported-algorithms.md) for key commitment; with and without signing. If you specify an algorithm suite that conflicts with your commitment policy, the AWS Encryption SDK returns an error. 

For help setting your commitment policy, see [Setting your commitment policy](migrate-commitment-policy.md).

## Digital signatures
<a name="digital-sigs"></a>

The AWS Encryption SDK encrypts your data using an authenticated encryption algorithm, AES-GCM, and the decryption process verifies the integrity and authenticity of an encrypted message without using a digital signature. But because AES-GCM uses symmetric keys, anyone who can decrypt the data key used to decrypt the ciphertext could also manually create a new encrypted ciphertext, causing a potential security concern. For instance, if you use an AWS KMS key as a wrapping key, a user with `kms:Decrypt` permissions could create encrypted ciphertexts without calling `kms:Encrypt`.

To avoid this issue, the AWS Encryption SDK supports adding an Elliptic Curve Digital Signature Algorithm (ECDSA) signature to the end of encrypted messages. When a signing algorithm suite is used, the AWS Encryption SDK generates a temporary private key and public key pair for each encrypted message. The AWS Encryption SDK stores the public key in the encryption context of the data key and discards the private key. This ensures that no one can create another signature that verifies with the public key. The algorithm binds the public key to the encrypted data key as additional authenticated data in the message header, preventing users who can only decrypt messages from altering the public key or affecting signature verification.

Signature verification adds a significant performance cost on decryption. If the users encrypting data and the users decrypting data are equally trusted, consider using an algorithm suite that does not include signing.

**Note**  
If the keyring or access to the wrapping cryptographic material doesn't delineate between encryptors and decryptors, digital signatures provide no cryptographic value.

[AWS KMS keyrings](use-kms-keyring.md), including the asymmetric RSA AWS KMS keyring, can delineate between encryptors and decryptors based on AWS KMS key policies and IAM policies.

Due to their cryptographic nature, the following keyrings cannot delineate between encryptors and decryptors:
+ AWS KMS Hierarchical keyring
+ AWS KMS ECDH keyring
+ Raw AES keyring
+ Raw RSA keyring
+ Raw ECDH keyring

# How the AWS Encryption SDK works
<a name="how-it-works"></a>

The workflows in this section explain how the AWS Encryption SDK encrypts data and decrypts [encrypted messages](concepts.md#message). These workflows describes the basic process using the default features. For details about defining and using custom components, see the GitHub repository for each supported [language implementation](programming-languages.md).

The AWS Encryption SDK uses envelope encryption to protect your data. Each message is encrypted under a unique data key. Then the data key is encrypted by the wrapping keys you specify. To decrypt the encrypted message, the AWS Encryption SDK uses the wrapping keys you specify to decrypt at least one encrypted data key. Then it can decrypt the ciphertext and return a plaintext message.

Need help with the terminology we use in the AWS Encryption SDK? See [Concepts in the AWS Encryption SDK](concepts.md).

## How the AWS Encryption SDK encrypts data
<a name="encrypt-workflow"></a>

The AWS Encryption SDK provides methods that encrypt strings, byte arrays, and byte streams. For code examples, see the Examples topic in each [Programming languages](programming-languages.md) section.

1. Create a [keyring](choose-keyring.md) (or [master key provider](concepts.md#master-key-provider)) that specifies the wrapping keys that protect your data.

1. Pass the keyring and plaintext data to an encryption method. We recommend that you pass in an optional, non-secret [encryption context](concepts.md#encryption-context).

1. The encryption method asks the keyring for encryption materials. The keyring returns unique data encryption keys for the message: one plaintext data key and one copy of that data key encrypted by each of the specified wrapping keys.

1. The encryption method uses the plaintext data key to encrypt the data, and then discards the plaintext data key. If you provide an encryption context (an AWS Encryption SDK [best practice](best-practices.md)), the encryption method cryptographically binds the encryption context to the encrypted data.

1. The encryption method returns an [encrypted message](concepts.md#message) that contains the encrypted data, the encrypted data keys, and other metadata, including the encryption context, if you used one.

## How the AWS Encryption SDK decrypts an encrypted message
<a name="decrypt-workflow"></a>

The AWS Encryption SDK provides methods that decrypt the [encrypted message](concepts.md#message) and return plaintext. For code examples, see the Examples topic in each [Programming languages](programming-languages.md) section.

The [keyring](choose-keyring.md) (or [master key provider](concepts.md#master-key-provider)) that decrypts the encrypted message must be compatible with the one used to encrypt the message. One of its wrapping keys must be able to decrypt an encrypted data key in the encrypted message. For information about compatibility with keyrings and master key providers, see [Keyring compatibility](choose-keyring.md#keyring-compatibility).

1. Create a keyring or master key provider with wrapping keys that can decrypt your data. You can use the same keyring that you provided to the encryption method or a different one.

1. Pass the [encrypted message](concepts.md#message) and the keyring to a decryption method.

1. The decryption method asks the keyring or master key provider to decrypt one of the encrypted data keys in the encrypted message. It passes in information from the encrypted message, including the encrypted data keys.

1. The keyring uses its wrapping keys to decrypt one of the encrypted data keys. If it's successful, the response includes the plaintext data key. If none of the wrapping keys specified by the keyring or master key provider can decrypt an encrypted data key, the decrypt call fails.

1. The decryption method uses the plaintext data key to decrypt the data, discards the plaintext data key, and returns the plaintext data.

# Supported algorithm suites in the AWS Encryption SDK
<a name="supported-algorithms"></a>

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

The AWS Encryption SDK algorithm suite uses the Advanced Encryption Standard (AES) algorithm in Galois/Counter Mode (GCM), known as AES-GCM, to encrypt raw data. The AWS Encryption SDK supports 256-bit, 192-bit, and 128-bit encryption keys. The length of the initialization vector (IV) is always 12 bytes. The length of the authentication tag is always 16 bytes.

By default, the AWS Encryption SDK uses an algorithm suite with AES-GCM with an HMAC-based extract-and-expand key derivation function ([HKDF](https://en.wikipedia.org/wiki/HKDF)), signing, and a 256-bit encryption key. If the [commitment policy](concepts.md#commitment-policy) requires [key commitment](concepts.md#key-commitment), the AWS Encryption SDK selects an algorithm suite that also supports key commitment; otherwise, it selects an algorithm suite with key derivation and signing, but not key commitment.

## Recommended: AES-GCM with key derivation, signing, and key commitment
<a name="recommended-algorithms"></a>

The AWS Encryption SDK recommends an algorithm suite that derives an AES-GCM encryption key by supplying a 256-bit data encryption key to the HMAC-based extract-and-expand key derivation function (HKDF). The AWS Encryption SDK adds an Elliptic Curve Digital Signature Algorithm (ECDSA) signature. To support [key commitment](concepts.md#key-commitment), this algorithm suite also derives a *key commitment string* – a non-secret data-key identifier – that is stored in the metadata of the encrypted message. This key commitment string is also derived through HKDF using a procedure similar to deriving the data encryption key.


**AWS Encryption SDK Algorithm Suite**  

| Encryption algorithm | Data encryption key length (in bits) | Key derivation algorithm | Signature algorithm | Key commitment | 
| --- | --- | --- | --- | --- | 
| AES-GCM | 256 | HKDF with SHA-384 | ECDSA with P-384 and SHA-384 | HKDF with SHA-512 | 

The HKDF helps you avoid accidental reuse of a data encryption key and reduces the risk of overusing a data key. 

For signing, this algorithm suite uses ECDSA with a cryptographic hash function algorithm (SHA-384). ECDSA is used by default, even when it is not specified by the policy for the underlying master key. [Message signing](concepts.md#digital-sigs) verifies the message sender was authorized to encrypt messages and provides non-repudiation. It is particularly useful when the authorization policy for a master key allows one set of users to encrypt data and a different set of users to decrypt data. 

Algorithm suites with key commitment ensure that each ciphertext decrypts to only one plaintext. They do this by validating the identity of the data key used as input to the encryption algorithm. When encrypting, these algorithm suites derive a key commitment string. Before decrypting, they validate that the data key matches the key commitment string. If it does not, the decrypt call fails.

## Other supported algorithm suites
<a name="other-algorithms"></a>

The AWS Encryption SDK supports the following alternate algorithm suites for backward compatibility. In general, we do not recommend these algorithm suites. However, we recognize that signing can hinder performance significantly, so we offer a key committing suite with key derivation for those cases. For applications that must make more significant performance tradeoffs, we continue to offer suites that lack signing, key commitment, and key derivation.

**AES-GCM without key commitment**  
Algorithm suites without key commitment do not validate the data key before decrypting. As a result, these algorithm suites might decrypt a single ciphertext into different plaintext messages. However, because algorithm suites with key commitment produce a [slightly larger (\$130 bytes) encrypted message](message-format.md) and take longer to process, they might not be the best choice for every application.   
The AWS Encryption SDK supports an algorithm suite with key derivation, key commitment, signing, and one with key derivation and key commitment, but not signing. We do not recommend using an algorithm suite without key commitment. If you must, we recommend an algorithm suite with key derivation and key commitment, but not signing. However, if your application performance profile supports using an algorithm suite, using an algorithm suite with key commitment, key derivation, and signing is a best practice.

**AES-GCM without signing**  
Algorithm suites without signing lack the ECDSA signature that provides authenticity and non-repudiation. Use these suites only when the users who encrypt data and those who decrypt data are equally trusted.   
When using an algorithm suite without signing, we recommend that you choose one with key derivation and key commitment. 

**AES-GCM without key derivation**  
Algorithm suites without key derivation use the data encryption key as the AES-GCM encryption key, instead of using a key derivation function to derive a unique key. We discourage using this suite to generate ciphertext, but the AWS Encryption SDK supports it for compatibility reasons.

For more information about how these suites are represented and used in the library, see [AWS Encryption SDK algorithms reference](algorithms-reference.md).