

# AWS Encryption SDK programming languages
<a name="programming-languages"></a>

The AWS Encryption SDK is available for the following programming languages. 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).

**Topics**
+ [C](c-language.md)
+ [.NET](dot-net.md)
+ [Go](go.md)
+ [Java](java.md)
+ [JavaScript](javascript.md)
+ [Python](python.md)
+ [Rust](rust.md)
+ [Command line interface](crypto-cli.md)

# AWS Encryption SDK for C
<a name="c-language"></a>

The AWS Encryption SDK for C provides a client-side encryption library for developers who are writing applications in C. It also serves as a foundation for implementations of the AWS Encryption SDK in higher-level programming languages.

Like all implementations of the AWS Encryption SDK, the AWS Encryption SDK for C offers advanced data protection features. These include [envelope encryption](concepts.md#envelope-encryption), additional authenticated data (AAD), and secure, authenticated, symmetric key [algorithm suites](concepts.md#crypto-algorithm), such as 256-bit AES-GCM with key derivation and signing.

All language-specific implementations of the AWS Encryption SDK are fully interoperable. For example, you can encrypt data with the AWS Encryption SDK for C and decrypt it with [any supported language implementation](programming-languages.md), including the [AWS Encryption CLI](crypto-cli.md).

The AWS Encryption SDK for C requires the AWS SDK for C\$1\$1 to interact with AWS Key Management Service (AWS KMS). You need to use it only if you're using the optional [AWS KMS keyring](use-kms-keyring.md). However, the AWS Encryption SDK doesn't require AWS KMS or any other AWS service.

**Learn More**
+ For details about programming with the AWS Encryption SDK for C, see the [C examples](c-examples.md), the [examples](https://github.com/aws/aws-encryption-sdk-c/tree/master/examples) in the [aws-encryption-sdk-c repository](https://github.com/aws/aws-encryption-sdk-c/) on GitHub, and the [AWS Encryption SDK for C API documentation](https://aws.github.io/aws-encryption-sdk-c/html/).
+ For a discussion about how to use the AWS Encryption SDK for C to encrypt data so that you can decrypt it in multiple AWS Regions, see [How to decrypt ciphertexts in multiple regions with the AWS Encryption SDK in C](https://aws.amazon.com/blogs/security/how-to-decrypt-ciphertexts-multiple-regions-aws-encryption-sdk-in-c/) in the AWS Security Blog.

**Topics**
+ [Installing](c-language-installation.md)
+ [Using the C SDK](c-language-using.md)
+ [Examples](c-examples.md)

# Installing the AWS Encryption SDK for C
<a name="c-language-installation"></a>

Install the latest version of the AWS Encryption SDK for C.

**Note**  
All versions of the AWS Encryption SDK for C earlier than 2.0.0 are in the [end-of-support phase](https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html#version-life-cycle).  
You can safely update from version 2.0.*x* and later to the latest version of the AWS Encryption SDK for C without any code or data changes. However, [ new security features](about-versions.md#version-2) introduced in version 2.0.*x* are not backward-compatible. To update from versions earlier than 1.7.*x* to version 2.0.*x* and later, you must first update to the latest 1.*x* version of the AWS Encryption SDK for C. For details, see [Migrating your AWS Encryption SDK](migration.md).

You can find detailed instructions for installing and building the AWS Encryption SDK for C in the [README file](https://github.com/aws/aws-encryption-sdk-c/#readme) of the [aws-encryption-sdk-c](https://github.com/aws/aws-encryption-sdk-c/) repository. It includes instructions for building on Amazon Linux, Ubuntu, macOS, and Windows platforms. 

Before you begin, decide whether you want to use [AWS KMS keyrings](use-kms-keyring.md) in the AWS Encryption SDK. If you use an AWS KMS keyring, you need to install the AWS SDK for C\$1\$1. The AWS SDK is required to interact with [AWS Key Management Service](https://docs.aws.amazon.com/kms/latest/developerguide/) (AWS KMS). When you use AWS KMS keyrings, the AWS Encryption SDK uses AWS KMS to generate and protect the encryption keys that protect your data. 

You do not need to install the AWS SDK for C\$1\$1 if you are using another keyring type, such as a raw AES keyring, a raw RSA keyring, or a multi-keyring that doesn't include an AWS KMS keyring. However, when using a raw keyring type, you need to generate and protect your own raw wrapping keys.

If you're having trouble with your installation, [file an issue](https://github.com/aws/aws-encryption-sdk-c/issues) in the `aws-encryption-sdk-c` repository or use any of the feedback links on this page.

# Using the AWS Encryption SDK for C
<a name="c-language-using"></a>

This topic explains some of the features of the AWS Encryption SDK for C that are not supported in other programming language implementations. 

The examples in this section show how to use [version 2.0.*x*](about-versions.md) and later of the AWS Encryption SDK for C. For examples that use earlier versions, find your release in the [Releases](https://github.com/aws/aws-encryption-sdk-c/releases) list of the [aws-encryption-sdk-c repository](https://github.com/aws/aws-encryption-sdk-c/) repository on GitHub.

For details about programming with the AWS Encryption SDK for C, see the [C examples](c-examples.md), the [examples](https://github.com/aws/aws-encryption-sdk-c/tree/master/examples) in the [aws-encryption-sdk-c repository](https://github.com/aws/aws-encryption-sdk-c/) on GitHub, and the [AWS Encryption SDK for C API documentation](https://aws.github.io/aws-encryption-sdk-c/html/).

See also: [Keyrings](choose-keyring.md)

**Topics**
+ [

## Patterns for encrypting and decrypting data
](#c-language-using-pattern)
+ [

## Reference counting
](#c-language-using-release)

## Patterns for encrypting and decrypting data
<a name="c-language-using-pattern"></a>

When you use the AWS Encryption SDK for C, you follow a pattern similar to this: create a [keyring](concepts.md#keyring), create a [CMM](concepts.md#crypt-materials-manager) that uses the keyring, create a session that uses the CMM (and keyring), and then process the session.

1. Load error strings.  
Call the `aws_cryptosdk_load_error_strings()` method in your C or C\$1\$1 code. It loads error information that is very useful for debugging.  
You only need to call it once, such as in your `main` method.  

```
/* Load error strings for debugging */
aws_cryptosdk_load_error_strings();
```

2. Create a keyring.  
Configure your [keyring](concepts.md#keyring) with the wrapping keys that you want to use to encrypt your data keys. This example uses an [AWS KMS keyring](use-kms-keyring.md) with one AWS KMS key, but you can use any type of keyring in its place.  
To identify an AWS KMS key in an encryption keyring in the AWS Encryption SDK for C, specify a [key ARN](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id-key-ARN) or [alias ARN](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id-alias-arn). In a decryption keyring, you must use a key ARN. For details, see [Identifying AWS KMS keys in an AWS KMS keyring](use-kms-keyring.md#kms-keyring-id).  

```
const char * KEY_ARN = "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab"    
struct aws_cryptosdk_keyring *kms_keyring = 
       Aws::Cryptosdk::KmsKeyring::Builder().Build(KEY_ARN);
```

3. Create a session.  
In the AWS Encryption SDK for C, you use a *session* to encrypt a single plaintext message or decrypt a single ciphertext message, regardless of its size. The session maintains the state of the message throughout its processing.   
Configure your session with an allocator, a keyring, and a mode: `AWS_CRYPTOSDK_ENCRYPT` or `AWS_CRYPTOSDK_DECRYPT`. If you need to change the mode of the session, use the `aws_cryptosdk_session_reset` method.  
When you create a session with a keyring, the AWS Encryption SDK for C automatically creates a default cryptographic materials manager (CMM) for you. You don't need to create, maintain, or destroy this object.   
For example, the following session uses the allocator and the keyring that was defined in step 1. When you encrypt data, the mode is `AWS_CRYPTOSDK_ENCRYPT`.  

```
struct aws_cryptosdk_session * session = aws_cryptosdk_session_new_from_keyring_2(allocator, AWS_CRYPTOSDK_ENCRYPT, kms_keyring);
```

4. Encrypt or decrypt the data.  
To process the data in the session, use the `aws_cryptosdk_session_process` method. If the input buffer is large enough to hold the entire plaintext, and the output buffer is large enough to hold the entire ciphertext, you can call `aws_cryptosdk_session_process_full`. However, if you need to handle streaming data, you can call `aws_cryptosdk_session_process` in a loop. For an example, see the [file\$1streaming.cpp](https://github.com/aws/aws-encryption-sdk-c/blob/master/examples/file_streaming.cpp) example. The `aws_cryptosdk_session_process_full` is introduced in AWS Encryption SDK versions 1.9.*x* and 2.2.*x*.  
When the session is configured to encrypt data, the plaintext fields describe the input and the ciphertext fields describe the output. The `plaintext` field holds the message that you want to encrypt and the `ciphertext` field gets the [encrypted message](message-format.md) that the encrypt method returns.   

```
/* Encrypting data */
aws_cryptosdk_session_process_full(session,
                                   ciphertext,
                                   ciphertext_buffer_size,
                                   &ciphertext_length,
                                   plaintext,
                                   plaintext_length)
```
When the session is configured to decrypt data, the ciphertext fields describe the input and the plaintext fields describe the output. The `ciphertext` field holds the [encrypted message](message-format.md) that the encrypt method returned, and the `plaintext` field gets the plaintext message that the decrypt method returns.  
To decrypt the data, call the `aws_cryptosdk_session_process_full` method.  

```
/* Decrypting data */
aws_cryptosdk_session_process_full(session,
                                   plaintext,
                                   plaintext_buffer_size,
                                   &plaintext_length,
                                   ciphertext,
                                   ciphertext_length)
```

## Reference counting
<a name="c-language-using-release"></a>

To prevent memory leaks, be sure to release your references to all objects that you create when you are finished with them. Otherwise, you end up with memory leaks. The SDK provides methods to make this task easier.

Whenever you create a parent object with one of the following child objects, the parent object gets and maintains a reference to the child object, as follows:
+ A [keyring](concepts.md#keyring), such as creating a session with a keyring
+ A default [cryptographic materials manager](concepts.md#crypt-materials-manager) (CMM), such as creating a session or custom CMM with a default CMM
+ A [data key cache](data-key-caching.md), such as creating a caching CMM with a keyring and cache

Unless you need an independent reference to the child object, you can release your reference to the child object as soon as you create the parent object. The remaining reference to the child object is released when the parent object is destroyed. This pattern ensures that you maintain the reference to each object only for as long as you need it, and you don't leak memory due to unreleased references. 

You are only responsible for releasing references to the child objects that you create explicitly. You are not responsible for managing references to any objects that the SDK creates for you. If the SDK creates an object, such as the default CMM that the `aws_cryptosdk_caching_cmm_new_from_keyring` method adds to a session, the SDK manages the creation and destruction of the object and its references.

In the following example, when you create a session with a [keyring](concepts.md#keyring), the session gets a reference to the keyring, and maintains that reference until the session is destroyed. If you do not need to maintain an additional reference to the keyring, you can use the `aws_cryptosdk_keyring_release` method to release the keyring object as soon as the session is created. This method decrements the reference count for the keyring. The session's reference to the keyring is released when you call `aws_cryptosdk_session_destroy` to destroy the session. 

```
// The session gets a reference to the keyring.
struct aws_cryptosdk_session *session =	
	aws_cryptosdk_session_new_from_keyring_2(alloc, AWS_CRYPTOSDK_ENCRYPT, keyring);

// After you create a session with a keyring, release the reference to the keyring object.
aws_cryptosdk_keyring_release(keyring);
```

For more complex tasks, such as reusing a keyring for multiple sessions or specifying an algorithm suite in a CMM, you might need to maintain an independent reference to the object. If so, don't call the release methods immediately. Instead, release your references when you are no longer using the objects, in addition to destroying the session.

This reference counting technique also works when you are using alternate CMMs, such as the caching CMM for [data key caching](data-key-caching.md). When you create a caching CMM from a cache and a keyring, the caching CMM gets a reference to both objects. Unless you need them for another task, you can release your independent references to the cache and keyring as soon as the caching CMM is created. Then, when you create a session with the caching CMM, you can release your reference to the caching CMM. 

Notice that you are only responsible for releasing references to objects that you create explicitly. Objects that the methods create for you, such as the default CMM that underlies the caching CMM, are managed by the method.

```
/ Create the caching CMM from a cache and a keyring.
struct aws_cryptosdk_cmm *caching_cmm = aws_cryptosdk_caching_cmm_new_from_keyring(allocator, cache, kms_keyring, NULL, 60, AWS_TIMESTAMP_SECS);

// Release your references to the cache and the keyring.
aws_cryptosdk_materials_cache_release(cache);
aws_cryptosdk_keyring_release(kms_keyring);

// Create a session with the caching CMM.
struct aws_cryptosdk_session *session = aws_cryptosdk_session_new_from_cmm_2(allocator, AWS_CRYPTOSDK_ENCRYPT, caching_cmm);

// Release your references to the caching CMM.
aws_cryptosdk_cmm_release(caching_cmm);

// ...

aws_cryptosdk_session_destroy(session);
```

# AWS Encryption SDK for C examples
<a name="c-examples"></a>

The following examples show you how to use the AWS Encryption SDK for C to encrypt and decrypt data. 

The examples in this section show how to use versions 2.0.*x* and later of the AWS Encryption SDK for C. For examples that use earlier versions, find your release in the [Releases](https://github.com/aws/aws-encryption-sdk-c/releases) list of the [aws-encryption-sdk-c repository](https://github.com/aws/aws-encryption-sdk-c/) repository on GitHub.

When you install and build the AWS Encryption SDK for C, the source code for these and other examples are included in the `examples` subdirectory, and they are compiled and built into the `build` directory. You can also find them in the [examples](https://github.com/aws/aws-encryption-sdk-c/tree/master/examples) subdirectory of the [aws-encryption-sdk-c](https://github.com/aws/aws-encryption-sdk-c/) repository on GitHub.

**Topics**
+ [

## Encrypting and decrypting strings
](#c-example-strings)

## Encrypting and decrypting strings
<a name="c-example-strings"></a>

The following example shows you how to use the AWS Encryption SDK for C to encrypt and decrypt a string.

This example features the [AWS KMS keyring](use-kms-keyring.md), a type of keyring that uses an AWS KMS key in [AWS Key Management Service (AWS KMS)](https://docs.aws.amazon.com/kms/latest/developerguide/) to generate and encrypt data keys. The example includes code written in C\$1\$1. The AWS Encryption SDK for C requires the AWS SDK for C\$1\$1 to call AWS KMS when using AWS KMS keyrings. If you're using a keyring that doesn't interact with AWS KMS, such as a raw AES keyring, a raw RSA keyring, or a multi-keyring that doesn't include an AWS KMS keyring, the AWS SDK for C\$1\$1 is not required.

For help creating an AWS KMS key, see [Creating Keys](https://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html) in the *AWS Key Management Service Developer Guide*. For help identifying the AWS KMS keys in an AWS KMS keyring, see [Identifying AWS KMS keys in an AWS KMS keyring](use-kms-keyring.md#kms-keyring-id).

**See the complete code sample**: [string.cpp](https://github.com/aws/aws-encryption-sdk-c/blob/master/examples/string.cpp)

**Topics**
+ [

### Encrypt a string
](#c-example-string-encrypt)
+ [

### Decrypt a string
](#c-example-string-decrypt)

### Encrypt a string
<a name="c-example-string-encrypt"></a>

The first part of this example uses an AWS KMS keyring with one AWS KMS key to encrypt a plaintext string. 

Step 1. Load error strings.  
Call the `aws_cryptosdk_load_error_strings()` method in your C or C\$1\$1 code. It loads error information that is very useful for debugging.  
You only need to call it once, such as in your `main` method.  

```
/* Load error strings for debugging */
aws_cryptosdk_load_error_strings();
```

Step 2: Construct the keyring.  
Create an AWS KMS keyring for encryption. The keyring in this example is configured with one AWS KMS key, but you can configure an AWS KMS keyring with multiple AWS KMS keys, including AWS KMS keys in different AWS Regions and different accounts.   
To identify an AWS KMS key in an encryption keyring in the AWS Encryption SDK for C, specify a [key ARN](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id-key-ARN) or [alias ARN](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id-alias-arn). In a decryption keyring, you must use a key ARN. For details, see [Identifying AWS KMS keys in an AWS KMS keyring](use-kms-keyring.md#kms-keyring-id).  
[Identifying AWS KMS keys in an AWS KMS keyring](use-kms-keyring.md#kms-keyring-id)  
When you create a keyring with multiple AWS KMS keys, you specify the AWS KMS key used to generate and encrypt the plaintext data key, and an optional array of additional AWS KMS keys that encrypt the same plaintext data key. In this case, you specify only the generator AWS KMS key.   
Before running this code, replace the example key ARN with a valid one.  

```
const char * key_arn = "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab";    

struct aws_cryptosdk_keyring *kms_keyring = 
       Aws::Cryptosdk::KmsKeyring::Builder().Build(key_arn);
```

Step 3: Create a session.  
Create a session using the allocator, a mode enumerator, and the keyring.  
Every session requires a mode: either `AWS_CRYPTOSDK_ENCRYPT` to encrypt or `AWS_CRYPTOSDK_DECRYPT` to decrypt. To change the mode of an existing session, use the `aws_cryptosdk_session_reset` method.  
After you create a session with the keyring, you can release your reference to the keyring using the method that the SDK provides. The session retains a reference to the keyring object during its lifetime. References to the keyring and session objects are released when you destroy the session. This [reference counting](c-language-using.md#c-language-using-release) technique helps to prevent memory leaks and to prevent the objects from being released while they are in use.  

```
struct aws_cryptosdk_session *session = 
       aws_cryptosdk_session_new_from_keyring_2(alloc, AWS_CRYPTOSDK_ENCRYPT, kms_keyring);

/* When you add the keyring to the session, release the keyring object */
aws_cryptosdk_keyring_release(kms_keyring);
```

Step 4: Set the encryption context.  
An [encryption context](concepts.md#encryption-context) is arbitrary, non-secret additional authenticated data. When you provide an encryption context on encrypt, the AWS Encryption SDK cryptographically binds the encryption context to the ciphertext so that the same encryption context is required to decrypt the data. Using an encryption context is optional, but we recommend it as a best practice.  
First, create a hash table that includes the encryption context strings.  

```
/* Allocate a hash table for the encryption context */
int set_up_enc_ctx(struct aws_allocator *alloc, struct aws_hash_table *my_enc_ctx) 

// Create encryption context strings
AWS_STATIC_STRING_FROM_LITERAL(enc_ctx_key1, "Example");
AWS_STATIC_STRING_FROM_LITERAL(enc_ctx_value1, "String");
AWS_STATIC_STRING_FROM_LITERAL(enc_ctx_key2, "Company");
AWS_STATIC_STRING_FROM_LITERAL(enc_ctx_value2, "MyCryptoCorp");

// Put the key-value pairs in the hash table
aws_hash_table_put(my_enc_ctx, enc_ctx_key1, (void *)enc_ctx_value1, &was_created)
aws_hash_table_put(my_enc_ctx, enc_ctx_key2, (void *)enc_ctx_value2, &was_created)
```
Get a mutable pointer to the encryption context in the session. Then, use the `aws_cryptosdk_enc_ctx_clone` function to copy the encryption context into the session. Keep the copy in `my_enc_ctx` so you can validate the value after decrypting the data.  
The encryption context is part of the session, not a parameter passed to the session process function. This guarantees that the same encryption context is used for every segment of a message, even if the session process function is called multiple times to encrypt the entire message.  

```
struct aws_hash_table *session_enc_ctx = aws_cryptosdk_session_get_enc_ctx_ptr_mut(session);

aws_cryptosdk_enc_ctx_clone(alloc, session_enc_ctx, my_enc_ctx)
```

Step 5: Encrypt the string.  
To encrypt the plaintext string, use the `aws_cryptosdk_session_process_full` method with the session in encryption mode. This method, introduced in AWS Encryption SDK versions 1.9.*x* and 2.2.*x*, is designed for non-streaming encryption and decryption. To handle streaming data, call the `aws_cryptosdk_session_process` in a loop.  
When encrypting, the plaintext fields are input fields; the ciphertext fields are output fields. When the processing is complete, the `ciphertext_output` field contains the [encrypted message](concepts.md#message), including the actual ciphertext, encrypted data keys, and the encryption context. You can decrypt this encrypted message by using the AWS Encryption SDK for any supported programming language.  

```
/* Gets the length of the plaintext that the session processed */
size_t ciphertext_len_output;
if (AWS_OP_SUCCESS != aws_cryptosdk_session_process_full(session,
                                  ciphertext_output,
                                  ciphertext_buf_sz_output,
                                  &ciphertext_len_output,
                                  plaintext_input,
                                  plaintext_len_input)) {
    aws_cryptosdk_session_destroy(session);
    return 8;
}
```

Step 6: Clean up the session.  
The final step destroys the session including references to the CMM and the keyring.  
If you prefer, instead of destroying the session, you can reuse the session with the same keyring and CMM to decrypt the string, or to encrypt or decrypt other messages. To use the session for decrypting, use the `aws_cryptosdk_session_reset` method to change the mode to `AWS_CRYPTOSDK_DECRYPT`.

### Decrypt a string
<a name="c-example-string-decrypt"></a>

The second part of this example decrypts an encrypted message that contains the ciphertext of the original string. 

Step 1: Load error strings.  
Call the `aws_cryptosdk_load_error_strings()` method in your C or C\$1\$1 code. It loads error information that is very useful for debugging.  
You only need to call it once, such as in your `main` method.  

```
/* Load error strings for debugging */
aws_cryptosdk_load_error_strings();
```

Step 2: Construct the keyring.  
When you decrypt data in AWS KMS, you pass in the [encrypted message](concepts.md#message) that the encrypt API returned. The [Decrypt API](https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.html) doesn't take an AWS KMS key as input. Instead, AWS KMS uses the same AWS KMS key to decrypt the ciphertext that it used to encrypt it. However, the AWS Encryption SDK lets you specify an AWS KMS keyring with AWS KMS keys on encrypt and decrypt.  
On decrypt, you can configure a keyring with only the AWS KMS keys that you want to use to decrypt the encrypted message. For example, you might want to create a keyring with only the AWS KMS key that is used by a particular role in your organization. The AWS Encryption SDK will never use an AWS KMS key unless it appears in the decryption keyring. If the SDK can't decrypt the encrypted data keys by using the AWS KMS keys in the keyring that you provide, either because none of AWS KMS keys in the keyring were used to encrypt any of the data keys, or because the caller doesn't have permission to use the AWS KMS keys in the keyring to decrypt, the decrypt call fails.  
When you specify an AWS KMS key for a decryption keyring, you must use its [key ARN](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id-key-ARN). [Alias ARNs](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id-alias-arn) are permitted only in encryption keyrings. For help identifying the AWS KMS keys in an AWS KMS keyring, see [Identifying AWS KMS keys in an AWS KMS keyring](use-kms-keyring.md#kms-keyring-id).  
In this example, we specify a keyring configured with the same AWS KMS key used to encrypt the string. Before running this code, replace the example key ARN with a valid one.  

```
const char * key_arn = "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab"    

struct aws_cryptosdk_keyring *kms_keyring =
        Aws::Cryptosdk::KmsKeyring::Builder().Build(key_arn);
```

Step 3: Create a session.  
Create a session using the allocator and the keyring. To configure the session for decryption, configure the session with the `AWS_CRYPTOSDK_DECRYPT` mode.   
After you create a session with a keyring, you can release your reference to the keyring using the method that the SDK provides. The session retains a reference to the keyring object during its lifetime, and both the session and keyring are released when you destroy the session. This reference counting technique helps to prevent memory leaks and to prevent the objects from being released while they are in use.  

```
struct aws_cryptosdk_session *session =	
	aws_cryptosdk_session_new_from_keyring_2(alloc, AWS_CRYPTOSDK_DECRYPT, kms_keyring);

/* When you add the keyring to the session, release the keyring object */
aws_cryptosdk_keyring_release(kms_keyring);
```

Step 4: Decrypt the string.  
To decrypt the string, use the `aws_cryptosdk_session_process_full` method with the session that is configured for decryption. This method, introduced in AWS Encryption SDK versions 1.9.*x* and 2.2.*x*, is designed for non-streaming encryption and decryption. To handle streaming data, call the `aws_cryptosdk_session_process` in a loop.  
When decrypting, the ciphertext fields are input fields and the plaintext fields are output fields. The `ciphertext_input` field holds the [encrypted message](message-format.md) that the encrypt method returned. When the processing is complete, the `plaintext_output` field contains the plaintext (decrypted) string.  

```
size_t plaintext_len_output;

if (AWS_OP_SUCCESS != aws_cryptosdk_session_process_full(session,
                                  plaintext_output,
                                  plaintext_buf_sz_output,
                                  &plaintext_len_output,
                                  ciphertext_input,
                                  ciphertext_len_input)) {
    aws_cryptosdk_session_destroy(session);
    return 13;
}
```

Step 5: Verify the encryption context.  
Be sure that the actual encryption context — the one that was used to decrypt the message — contains the encryption context that you provided when encrypting the message. The actual encryption context might include extra pairs, because the [cryptographic materials manager](concepts.md#crypt-materials-manager) (CMM) can add pairs to the provided encryption context before encrypting the message.  
In the AWS Encryption SDK for C, you are not required to provide an encryption context when decrypting because the encryption context is included in the encrypted message that the SDK returns. But, before it returns the plaintext message, your decrypt function should verify that all pairs in the provided encryption context appear in the encryption context that was used to decrypt the message.  
First, get a read-only pointer to the hash table in the session. This hash table contains the encryption context that was used to decrypt the message.   

```
const struct aws_hash_table *session_enc_ctx = aws_cryptosdk_session_get_enc_ctx_ptr(session);
```
Then, loop through the encryption context in the `my_enc_ctx` hash table that you copied when encrypting. Verify that each pair in the `my_enc_ctx` hash table that was used to encrypt appears in the `session_enc_ctx` hash table that was used to decrypt. If any key is missing, or that key has a different value, stop processing and write an error message.  

```
for (struct aws_hash_iter iter = aws_hash_iter_begin(my_enc_ctx); !aws_hash_iter_done(&iter);
      aws_hash_iter_next(&iter)) {
     struct aws_hash_element *session_enc_ctx_kv_pair;
     aws_hash_table_find(session_enc_ctx, iter.element.key, &session_enc_ctx_kv_pair)

    if (!session_enc_ctx_kv_pair ||
        !aws_string_eq(
            (struct aws_string *)iter.element.value, (struct aws_string *)session_enc_ctx_kv_pair->value)) {
        fprintf(stderr, "Wrong encryption context!\n");
        abort();
    }
}
```

Step 6: Clean up the session.  
After you verify the encryption context, you can destroy the session, or reuse it. If you need to reconfigure the session, use the `aws_cryptosdk_session_reset` method.  

```
aws_cryptosdk_session_destroy(session);
```

# AWS Encryption SDK for .NET
<a name="dot-net"></a>

The AWS Encryption SDK for .NET is a client-side encryption library for developers who are writing applications in C\$1 and other .NET programming languages. It is supported on Windows, macOS, and Linux.

**Note**  
Version 4.0.0 of the AWS Encryption SDK for .NET deviates from the AWS Encryption SDK Message Specification. As a result, messages encrypted by version 4.0.0 can only be decrypted by version 4.0.0 or later of the AWS Encryption SDK for .NET. They cannot be decrypted by any other programming language implementation.  
Version 4.0.1 of the AWS Encryption SDK for .NET writes messages according to the AWS Encryption SDK Message Specification, and is interoperable with other programming language implementations. By default, version 4.0.1 can read messages encrypted by version 4.0.0. However, if you do not want to decrypt messages encrypted by version 4.0.0, you can specify the [https://github.com/aws/aws-encryption-sdk/tree/mainline/AwsEncryptionSDK/runtimes/net/Examples/NetV4_0_0Example.cs](https://github.com/aws/aws-encryption-sdk/tree/mainline/AwsEncryptionSDK/runtimes/net/Examples/NetV4_0_0Example.cs) property to prevent the client from reading these messages. For more information, see the [v4.0.1 release notes](https://github.com/aws/aws-encryption-sdk/releases/tag/v4.0.1) in the aws-encryption-sdk repository on GitHub.

The AWS Encryption SDK for .NET differs from some of the other programming language implementations of the AWS Encryption SDK in the following ways:
+ No support for [data key caching](data-key-caching.md)
**Note**  
Version 4.*x* of the AWS Encryption SDK for .NET supports the [AWS KMS Hierarchical keyring](use-hierarchical-keyring.md), an alternative cryptographic materials caching solution.
+ No support for streaming data
+ [No logging or stack traces](#dot-net-debugging) from the AWS Encryption SDK for .NET
+ [Requires the AWS SDK for .NET](#dot-net-install)

The AWS Encryption SDK for .NET includes all of the security features introduced in versions 2.0.*x* and later of other language implementations of the AWS Encryption SDK. However, if you are using the AWS Encryption SDK for .NET to decrypt data that was encrypted by a pre-2.0.*x* version another language implementation of the AWS Encryption SDK, you might need to adjust your [commitment policy](concepts.md#commitment-policy). For details, see [How to set your commitment policy](migrate-commitment-policy.md#migrate-commitment-step1).

The AWS Encryption SDK for .NET is a product of the AWS Encryption SDK in [Dafny](https://github.com/dafny-lang/dafny/blob/master/README.md), a formal verification language in which you write specifications, the code to implement them, and the proofs to test them. The result is a library that implements the features of the AWS Encryption SDK in a framework that assures functional correctness.

**Learn More**
+ For examples showing how to configure options in the AWS Encryption SDK, such as specifying an alternate algorithm suite, limiting encrypted data keys, and using AWS KMS multi-Region keys, see [Configuring the AWS Encryption SDK](configure.md).
+ For details about programming with the AWS Encryption SDK for .NET, see the [https://github.com/aws/aws-encryption-sdk/tree/mainline/AwsEncryptionSDK/runtimes/net/](https://github.com/aws/aws-encryption-sdk/tree/mainline/AwsEncryptionSDK/runtimes/net/) directory of the aws-encryption-sdk repository on GitHub.

**Topics**
+ [Install and build](#dot-net-install)
+ [Debugging](#dot-net-debugging)
+ [Examples](dot-net-examples.md)

## Installing the AWS Encryption SDK for .NET
<a name="dot-net-install"></a>

The AWS Encryption SDK for .NET is available as the [https://www.nuget.org/packages/AWS.Cryptography.EncryptionSDK](https://www.nuget.org/packages/AWS.Cryptography.EncryptionSDK) package in NuGet. For details about installing and building the AWS Encryption SDK for .NET, see the [README.md](https://github.com/aws/aws-encryption-sdk/tree/mainline/AwsEncryptionSDK/runtimes/net/#readme) file in the `aws-encryption-sdk-net` repository.

**Version 3.x**  
Version 3.*x* of the AWS Encryption SDK for .NET supports .NET Framework 4.5.2 – 4.8 only on Windows. It supports .NET Core 3.0\$1 and .NET 5.0 and later on all supported operating systems.

**Version 4.x**  
Version 4.*x* of the AWS Encryption SDK for .NET supports .NET 6.0 and .NET Framework net48 and later. Version 4.*x* requires the AWS SDK for .NET v3.

**Version 5.x**  
Version 5.*x* of the AWS Encryption SDK for .NET supports .NET 6.0 and .NET Framework net48 and later. Version 5.*x* requires version 2.*x* of the Material Providers Library (MPL) and the AWS SDK for .NET v4.

The AWS Encryption SDK for .NET requires the SDK for .NET even if you aren't using AWS Key Management Service (AWS KMS) keys. It's installed with the NuGet package. However, unless you are using AWS KMS keys, AWS Encryption SDK for .NET does not require an AWS account, AWS credentials, or interaction with any AWS service. For help setting up an AWS account if you need it, see [Using the AWS Encryption SDK with AWS KMS](getting-started.md).

## Debugging the AWS Encryption SDK for .NET
<a name="dot-net-debugging"></a>

The AWS Encryption SDK for .NET does not generate any logs. Exceptions in the AWS Encryption SDK for .NET generate an exception message, but no stack traces.

To help you debug, be sure to enable logging in the SDK for .NET. The logs and error messages from the SDK for .NET can help you distinguish errors arising in the SDK for .NET from those in the AWS Encryption SDK for .NET. For help with SDK for .NET logging, see [AWSLogging](https://docs.aws.amazon.com/sdk-for-net/v4/developer-guide/net-dg-config-other.html#config-setting-awslogging) in the *AWS SDK for .NET Developer Guide*. (To see the topic, expand the **Open to view .NET Framework content** section.)

# AWS Encryption SDK for .NET examples
<a name="dot-net-examples"></a>

The following examples show the basic coding patterns that you use when programming with the AWS Encryption SDK for .NET. Specifically, you instantiate the AWS Encryption SDK and the material providers library. Then, before calling each method, you instantiate an object that defines the input for the method. This is much like the coding pattern you use in the SDK for .NET.

For examples showing how to configure options in the AWS Encryption SDK, such as specifying an alternate algorithm suite, limiting encrypted data keys, and using AWS KMS multi-Region keys, see [Configuring the AWS Encryption SDK](configure.md).

For more examples of programming with the AWS Encryption SDK for .NET, see the [examples](https://github.com/aws/aws-encryption-sdk/tree/mainline/AwsEncryptionSDK/runtimes/net/Examples) in the `aws-encryption-sdk-net` directory of the `aws-encryption-sdk` repository on GitHub.

## Encrypting data in the AWS Encryption SDK for .NET
<a name="dot-net-example-encrypt"></a>

This example shows the basic pattern for encrypting data. It encrypts a small file with data keys that are protected by one AWS KMS wrapping key.

Step 1: Instantiate the AWS Encryption SDK and the material providers library.  
Begin by instantiating the AWS Encryption SDK and the material providers library. You'll use the methods in the AWS Encryption SDK to encrypt and decrypt data. You'll use the methods in the material providers library to create the keyrings that specify which keys protect your data.  
The way you instantiate the AWS Encryption SDK and the material providers library differs between versions 3.*x* and 4.*x* of the AWS Encryption SDK for .NET. All of the following steps are the same for both version 3.*x* and 4.*x* of the AWS Encryption SDK for .NET.  

```
// Instantiate the AWS Encryption SDK and material providers
var encryptionSdk = AwsEncryptionSdkFactory.CreateDefaultAwsEncryptionSdk();
var materialProviders =
    AwsCryptographicMaterialProvidersFactory.CreateDefaultAwsCryptographicMaterialProviders();
```

```
// Instantiate the AWS Encryption SDK and material providers
var esdk =  new ESDK(new AwsEncryptionSdkConfig());
var mpl = new MaterialProviders(new MaterialProvidersConfig());
```

Step 2: Create an input object for the keyring.  
Each method that creates a keyring has a corresponding input object class. For example, to create the input object for the `CreateAwsKmsKeyring()` method, create an instance of the `CreateAwsKmsKeyringInput` class.  
Even though the input for this keyring doesn't specify a [generator key](use-kms-keyring.md#kms-keyring-encrypt), the single KMS key specified by the `KmsKeyId` parameter is the generator key. It generates and encrypts the data key that encrypts the data.   
This input object requires an AWS KMS client for the AWS Region of the KMS key. To create a AWS KMS client, instantiate the `AmazonKeyManagementServiceClient` class in the SDK for .NET. Calling the `AmazonKeyManagementServiceClient()` constructor with no parameters creates a client with the default values.  
In an AWS KMS keyring used for encrypting with the AWS Encryption SDK for .NET, you can [identify the KMS keys](use-kms-keyring.md#kms-keyring-id) by using the key ID, key ARN, alias name, or alias ARN. In an AWS KMS keyring used for decrypting, you must use a key ARN to identify each KMS key. If you plan to reuse your encryption keyring for decrypting, use a key ARN identifier for all KMS keys.  

```
string keyArn = "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab";

// Instantiate the keyring input object
var kmsKeyringInput = new CreateAwsKmsKeyringInput
{    
    KmsClient = new AmazonKeyManagementServiceClient(),
    KmsKeyId = keyArn
};
```

Step 3: Create the keyring.  
To create the keyring, call the keyring method with the keyring input object. This example uses the `CreateAwsKmsKeyring()` method, which takes just one KMS key.  

```
var keyring = materialProviders.CreateAwsKmsKeyring(kmsKeyringInput);
```

Step 4: Define an encryption context.  
An [encryption context](concepts.md#encryption-context) is an optional, but strongly recommended element of cryptographic operations in the AWS Encryption SDK. You can define one or more non-secret key-value pairs.  
With version 4.*x* of the AWS Encryption SDK for .NET, you can require an encryption context in all encrypt requests with the [required encryption context CMM](configure.md#config-required-encryption-context-cmm).

```
// Define the encryption context
var encryptionContext = new Dictionary<string, string>()
{
    {"purpose", "test"}
};
```

Step 5: Create the input object for encrypting.  
Before calling the `Encrypt()` method, create an instance of the `EncryptInput` class.  

```
string plaintext = File.ReadAllText("C:\\Documents\\CryptoTest\\TestFile.txt");
            
// Define the encrypt input
var encryptInput = new EncryptInput
{
    Plaintext = plaintext,
    Keyring = keyring,
    EncryptionContext = encryptionContext
};
```

Step 6: Encrypt the plaintext.  
Use the `Encrypt()` method of the AWS Encryption SDK to encrypt the plaintext using the keyring you defined.   
The `EncryptOutput` that the `Encrypt() `method returns has methods for getting the encrypted message (`Ciphertext`), encryption context, and algorithm suite.   

```
var encryptOutput = encryptionSdk.Encrypt(encryptInput);
```

Step 7: Get the encrypted message.  
The `Decrypt()` method in the AWS Encryption SDK for .NET takes the `Ciphertext` member of the `EncryptOutput` instance.  
The `Ciphertext` member of the `EncryptOutput` object is the [encrypted message](concepts.md#message), a portable object that includes the encrypted data, encrypted data keys, and metadata, including the encryption context. You can safely store the encrypted message for an extended time or submit it to the `Decrypt()` method to recover the plaintext.   

```
var encryptedMessage = encryptOutput.Ciphertext;
```

## Decrypting in strict mode in the AWS Encryption SDK for .NET
<a name="dot-net-decrypt-strict"></a>

Best practices recommend that you specify the keys that you use to decrypt data, an option known as *strict mode*. The AWS Encryption SDK uses only the KMS keys that you specify in your keyring to decrypt the ciphertext. The keys in your decryption keyring must include at least one of the keys that encrypted the data.

This example shows the basic pattern of decrypting in strict mode with the AWS Encryption SDK for .NET.

Step 1: Instantiate the AWS Encryption SDK and material providers library.  

```
// Instantiate the AWS Encryption SDK and material providers
var esdk =  new ESDK(new AwsEncryptionSdkConfig());
var mpl = new MaterialProviders(new MaterialProvidersConfig());
```

Step 2: Create the input object for your keyring.  
To specify the parameters for the keyring method, create an input object. Each keyring method in the AWS Encryption SDK for .NET has a corresponding input object. Because this example uses the `CreateAwsKmsKeyring()` method to create the keyring, it instantiates the `CreateAwsKmsKeyringInput` class for the input.  
In a decryption keyring, you must use a key ARN to identify KMS keys.  

```
string keyArn = "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab";

// Instantiate the keyring input object
var kmsKeyringInput = new CreateAwsKmsKeyringInput
{
    KmsClient = new AmazonKeyManagementServiceClient(),
    KmsKeyId = keyArn
};
```

Step 3: Create the keyring.  
To create the decryption keyring, this example uses the `CreateAwsKmsKeyring()` method and the keyring input object.  

```
var keyring = materialProviders.CreateAwsKmsKeyring(kmsKeyringInput);
```

Step 4: Create the input object for decrypting.  
To create the input object for the `Decrypt()` method, instantiate the `DecryptInput` class.  
The `Ciphertext` parameter of the `DecryptInput()` constructor takes the `Ciphertext` member of the `EncryptOutput` object that the `Encrypt()` method returned. The `Ciphertext` property represents the [encrypted message](concepts.md#message), which includes the encrypted data, encrypted data keys, and metadata that the AWS Encryption SDK needs to decrypt the message.  
With version 4.*x* of the AWS Encryption SDK for .NET, you can use the optional `EncryptionContext` parameter to specify your encryption context in the `Decrypt()` method.  
Use the `EncryptionContext` parameter to verify that the encryption context used on encrypt *is included* in the encryption context used to decrypt the ciphertext. The AWS Encryption SDK adds pairs to the encryption context, including the digital signature if you're using an algorithm suite with signing, such as the default algorithm suite.  

```
var encryptedMessage = encryptOutput.Ciphertext;

var decryptInput = new DecryptInput
{
    Ciphertext = encryptedMessage,
    Keyring = keyring,
    EncryptionContext = encryptionContext // OPTIONAL
};
```

Step 5: Decrypt the ciphertext.  

```
var decryptOutput = encryptionSdk.Decrypt(decryptInput);
```

Step 6: Verify the encryption context – Version 3.*x*  
The `Decrypt()` method of version 3.*x* of the AWS Encryption SDK for .NET does not take an encryption context. It gets the encryption context values from the metadata in the encrypted message. However, before returning or using the plaintext, it's a best practice to verify that encryption context that was used to decrypt the ciphertext includes the encryption context you provided when encrypting.   
Verify that the encryption context used on encrypt *is included* in the encryption context that used to decrypt the ciphertext. The AWS Encryption SDK adds pairs to the encryption context, including the digital signature if you're using an algorithm suite with signing, such as the default algorithm suite.  

```
// Verify the encryption context
string contextKey = "purpose";
string contextValue = "test";

if (!decryptOutput.EncryptionContext.TryGetValue(contextKey, out var decryptContextValue)
    || !decryptContextValue.Equals(contextValue))
{
    throw new Exception("Encryption context does not match expected values");
}
```

## Decrypting with a discovery keyring in the AWS Encryption SDK for .NET
<a name="dot-net-decrypt-discovery"></a>

Rather than specifying the KMS keys for decryption, you can provide a AWS KMS *discovery keyring*, which is a keyring that doesn't specify any KMS keys. A discovery keyring lets the AWS Encryption SDK decrypt the data by using whichever KMS key encrypted it, provided that the caller has decrypt permission on the key. For best practices, add a discovery filter that limits the KMS keys that can be used to those in particular AWS accounts of a specified partition. 

The AWS Encryption SDK for .NET provides a basic discovery keyring that requires an AWS KMS client and a discovery multi-keyring that requires you to specify one or more AWS Regions. The client and Regions both limit the KMS keys that can be used to decrypt the encrypted message. The input objects for both keyrings take the recommended discovery filter.

The following example shows the pattern for decrypting data with an AWS KMS discovery keyring and discovery filter.

Step 1: Instantiate the AWS Encryption SDK and the material providers library.  

```
// Instantiate the AWS Encryption SDK and material providers
var esdk =  new ESDK(new AwsEncryptionSdkConfig());
var mpl = new MaterialProviders(new MaterialProvidersConfig());
```

Step 2: Create the input object for the keyring.  
To specify the parameters for the keyring method, create an input object. Each keyring method in the AWS Encryption SDK for .NET has a corresponding input object. Because this example uses the `CreateAwsKmsDiscoveryKeyring()` method to create the keyring, it instantiates the `CreateAwsKmsDiscoveryKeyringInput` class for the input.  

```
List<string> accounts = new List<string> { "111122223333" };

var discoveryKeyringInput = new CreateAwsKmsDiscoveryKeyringInput
{
    KmsClient = new AmazonKeyManagementServiceClient(),
    DiscoveryFilter = new DiscoveryFilter()
    {
        AccountIds = accounts,
        Partition = "aws"
    }
};
```

Step 3: Create the keyring.  
To create the decryption keyring, this example uses the `CreateAwsKmsDiscoveryKeyring()` method and the keyring input object.  

```
var discoveryKeyring = materialProviders.CreateAwsKmsDiscoveryKeyring(discoveryKeyringInput);
```

Step 4: Create the input object for decrypting.  
To create the input object for the `Decrypt()` method, instantiate the `DecryptInput` class. The value of the `Ciphertext` parameter is the `Ciphertext` member of the `EncryptOutput` object that the `Encrypt()` method returns.  
With version 4.*x* of the AWS Encryption SDK for .NET, you can use the optional `EncryptionContext` parameter to specify your encryption context in the `Decrypt()` method.  
Use the `EncryptionContext` parameter to verify that the encryption context used on encrypt *is included* in the encryption context used to decrypt the ciphertext. The AWS Encryption SDK adds pairs to the encryption context, including the digital signature if you're using an algorithm suite with signing, such as the default algorithm suite.  

```
var ciphertext = encryptOutput.Ciphertext;

var decryptInput = new DecryptInput
{
    Ciphertext = ciphertext,
    Keyring = discoveryKeyring,
    EncryptionContext = encryptionContext // OPTIONAL
    
};
var decryptOutput = encryptionSdk.Decrypt(decryptInput);
```

Step 5: Verify the encryption context – Version 3.*x*  
The `Decrypt()` method of version 3.*x* of the AWS Encryption SDK for .NET does not take an encryption context on `Decrypt()`. It gets the encryption context values from the metadata in the encrypted message. However, before returning or using the plaintext, it's a best practice to verify that encryption context that was used to decrypt the ciphertext includes the encryption context you provided when encrypting.   
Verify that the encryption context used on encrypt *is included* in the encryption context that was used to decrypt the ciphertext. The AWS Encryption SDK adds pairs to the encryption context, including the digital signature if you're using an algorithm suite with signing, such as the default algorithm suite.   

```
// Verify the encryption context
string contextKey = "purpose";
string contextValue = "test";

if (!decryptOutput.EncryptionContext.TryGetValue(contextKey, out var decryptContextValue)
    || !decryptContextValue.Equals(contextValue))
{
    throw new Exception("Encryption context does not match expected values");
}
```

# AWS Encryption SDK for Go
<a name="go"></a>

This topic explains how to install and use the AWS Encryption SDK for Go. For details about programming with the AWS Encryption SDK for Go, see [go](https://github.com/aws/aws-encryption-sdk/tree/mainline/releases/go/encryption-sdk/) directory of the aws-encryption-sdk repository on GitHub.

The AWS Encryption SDK for Go differs from some of the other programming language implementations of the AWS Encryption SDK in the following ways:
+ No support for [data key caching](data-key-caching.md). However, the AWS Encryption SDK for Go supports the [AWS KMS Hierarchical keyring](use-hierarchical-keyring.md), an alternative cryptographic materials caching solution.
+ No support for streaming data

The AWS Encryption SDK for Go includes all of the security features introduced in versions 2.0.*x* and later of other language implementations of the AWS Encryption SDK. However, if you are using the AWS Encryption SDK for Go to decrypt data that was encrypted by a pre-2.0.*x* version another language implementation of the AWS Encryption SDK, you might need to adjust your [commitment policy](concepts.md#commitment-policy). For details, see [How to set your commitment policy](migrate-commitment-policy.md#migrate-commitment-step1).

The AWS Encryption SDK for Go is a product of the AWS Encryption SDK in [Dafny](https://github.com/dafny-lang/dafny/blob/master/README.md), a formal verification language in which you write specifications, the code to implement them, and the proofs to test them. The result is a library that implements the features of the AWS Encryption SDK in a framework that assures functional correctness.

**Learn More**
+ For examples showing how to configure options in the AWS Encryption SDK, such as specifying an alternate algorithm suite, limiting encrypted data keys, and using AWS KMS multi-Region keys, see [Configuring the AWS Encryption SDK](configure.md).
+ For examples showing how to configure and use the AWS Encryption SDK for Go, see the [Go examples](https://github.com/aws/aws-encryption-sdk/tree/mainline/releases/go/encryption-sdk/examples) in the aws-encryption-sdk repository on GitHub.

**Topics**
+ [

## Prerequisites
](#prerequisites-go)
+ [

## Installation
](#go-installation)

## Prerequisites
<a name="prerequisites-go"></a>

Before you install the AWS Encryption SDK for Go, be sure you have the following prerequisites.

**A supported version of Go**  
Go 1.23 or later is required by AWS Encryption SDK for Go.  
For more information on downloading and installing Go, see [Go installation](https://go.dev/doc/install).

## Installation
<a name="go-installation"></a>

Install the latest version of the AWS Encryption SDK for Go. For details on installing and building the AWS Encryption SDK for Go, see the [README.md](https://github.com/aws/aws-encryption-sdk/tree/mainline/releases/go/encryption-sdk/README.md) in the go directory of the aws-encryption-sdk repository on GitHub.

**To install the latest version**
+ Install the AWS Encryption SDK for Go

  ```
  go get github.com/aws/aws-encryption-sdk/releases/go/encryption-sdk@latest
  ```
+ Install the [Cryptographic Material Providers Library](https://github.com/aws/aws-cryptographic-material-providers-library) (MPL)

  ```
  go get github.com/aws/aws-cryptographic-material-providers-library/releases/go/mpl
  ```

# AWS Encryption SDK for Java
<a name="java"></a>

This topic explains how to install and use the AWS Encryption SDK for Java. For details about programming with the AWS Encryption SDK for Java, see the [aws-encryption-sdk-java](https://github.com/aws/aws-encryption-sdk-java/) repository on GitHub. For API documentation, see the [Javadoc](https://aws.github.io/aws-encryption-sdk-java/) for the AWS Encryption SDK for Java.

**Topics**
+ [

## Prerequisites
](#java-prerequisites)
+ [

## Installation
](#java-installation)
+ [Examples](java-example-code.md)

## Prerequisites
<a name="java-prerequisites"></a>

Before you install the AWS Encryption SDK for Java, be sure you have the following prerequisites.

**A Java development environment**  
You will need Java 8 or later. On the Oracle website, go to [Java SE Downloads](https://www.oracle.com/java/technologies/downloads/), and then download and install the Java SE Development Kit (JDK).  
If you use the Oracle JDK, you must also download and install the [Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files](http://www.oracle.com/java/technologies/javase-jce8-downloads.html).

**Bouncy Castle**  
The AWS Encryption SDK for Java requires [Bouncy Castle](https://www.bouncycastle.org/download/bouncy-castle-java/).   
+ AWS Encryption SDK for Java versions 1.6.1 and later use Bouncy Castle to serialize and deserialize cryptographic objects. You can use Bouncy Castle or [Bouncy Castle FIPS](https://www.bouncycastle.org/about/bouncy-castle-fips-faq/) to satisfy this requirement. For help installing and configuring Bouncy Castle FIPS, see [BC FIPS Documentation](https://www.bouncycastle.org/documentation/), especially the **User Guides** and **Security Policy** PDFs.
+ Earlier versions of the AWS Encryption SDK for Java use Bouncy Castle's cryptography API for Java. This requirement is satisfied only by non-FIPS Bouncy Castle.
If you don't have Bouncy Castle, go to [Download Bouncy Castle for Java](https://bouncycastle.org/download/bouncy-castle-java/) to download the provider file that corresponds to your JDK. You can also use [Apache Maven](https://maven.apache.org/) to get the artifact for the standard Bouncy Castle provider ([bcprov-ext-jdk15on](https://mvnrepository.com/artifact/org.bouncycastle/bcprov-ext-jdk15on)) or the artifact for Bouncy Castle FIPS ([bc-fips](https://mvnrepository.com/artifact/org.bouncycastle/bc-fips)).

**AWS SDK for Java**  
Version 3.*x* of the AWS Encryption SDK for Java requires the AWS SDK for Java 2.x, even if you don't use AWS KMS keyrings.  
Version 2.*x* or earlier of the AWS Encryption SDK for Java does not require the AWS SDK for Java. However, the AWS SDK for Java is required to use [AWS Key Management Service](https://aws.amazon.com/kms/) (AWS KMS) as a master key provider. Beginning in the AWS Encryption SDK for Java version 2.4.0, the AWS Encryption SDK for Java supports both version 1.x and 2.x of the AWS SDK for Java. AWS Encryption SDK code for the AWS SDK for Java 1.x and 2.x are interoperable. For example, you can encrypt data with AWS Encryption SDK code that supports AWS SDK for Java 1.x and decrypt it using code that supports AWS SDK for Java 2.x (or vice versa). Versions of the AWS Encryption SDK for Java earlier than 2.4.0 support only AWS SDK for Java 1.x. For information about updating your version of the AWS Encryption SDK, see [Migrating your AWS Encryption SDK](migration.md).  
When updating your AWS Encryption SDK for Java code from the AWS SDK for Java 1.x to AWS SDK for Java 2.x, replace references to the [`AWSKMS` interface](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/kms/package-summary.html) in AWS SDK for Java 1.x with references to the [`KmsClient` interface](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/kms/package-summary.html) in AWS SDK for Java 2.x. The AWS Encryption SDK for Java does not support the [`KmsAsyncClient` interface](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/kms/KmsAsyncClient.html). Also, update your code to use the AWS KMS-related objects in the `kmssdkv2` namespace, instead of the `kms` namespace.   
To install the AWS SDK for Java, use Apache Maven.   
+ To [import the entire AWS SDK for Java](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/setup-project-maven.html#build-the-entire-sdk-into-your-project) as a dependency, declare it in your `pom.xml` file.
+ To create a dependency only for the AWS KMS module in AWS SDK for Java 1.x, follow the instructions for [specifying particular modules](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/setup-project-maven.html#modules-dependencies), and set the `artifactId` to `aws-java-sdk-kms`.
+ To create a dependency only for the AWS KMS module in AWS SDK for Java 2.x, follow the instructions for [specifying particular modules](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/setup-project-maven.html#modules-dependencies). Set the `groupId` to `software.amazon.awssdk` and the `artifactId` to `kms`.
For more changes, see [What's different between the AWS SDK for Java 1.x and 2.x](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/migration-whats-different.html) in the AWS SDK for Java 2.x Developer Guide.  
Java examples in the AWS Encryption SDK Developer Guide use the AWS SDK for Java 2.x.

## Installation
<a name="java-installation"></a>

Install the latest version of the AWS Encryption SDK for Java.

**Note**  
All versions of the AWS Encryption SDK for Java earlier than 2.0.0 are in the [end-of-support phase](https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html#version-life-cycle).  
You can safely update from version 2.0.*x* and later to the latest version of the AWS Encryption SDK for Java without any code or data changes. However, [ new security features](about-versions.md#version-2) introduced in version 2.0.*x* are not backward-compatible. To update from versions earlier than 1.7.*x* to version 2.0.*x* and later, you must first update to the latest 1.*x* version of the AWS Encryption SDK. For details, see [Migrating your AWS Encryption SDK](migration.md).

You can install the AWS Encryption SDK for Java in the following ways.

**Manually**  
To install the AWS Encryption SDK for Java, clone or download the [aws-encryption-sdk-java](https://github.com/aws/aws-encryption-sdk-java/) GitHub repository.

**Using Apache Maven**  
The AWS Encryption SDK for Java is available through [Apache Maven](https://maven.apache.org/) with the following dependency definition.  

```
<dependency>
  <groupId>com.amazonaws</groupId>
  <artifactId>aws-encryption-sdk-java</artifactId>
  <version>3.0.0</version>
</dependency>
```

After you install the SDK, get started by looking at the [example Java code](java-example-code.md) in this guide and the [Javadoc on GitHub](https://aws.github.io/aws-encryption-sdk-java/).

# AWS Encryption SDK for Java examples
<a name="java-example-code"></a>

The following examples show you how to use the AWS Encryption SDK for Java to encrypt and decrypt data. These examples show how to use version 3.*x* and later of the AWS Encryption SDK for Java. Version 3.*x* of the AWS Encryption SDK for Java requires the AWS SDK for Java 2.x. Version 3.*x* of the AWS Encryption SDK for Java replaces [master key providers](concepts.md#master-key-provider) with [keyrings](concepts.md#keyring). For examples that use earlier versions, find your release in the [Releases](https://github.com/aws/aws-encryption-sdk-java/releases) list of the [aws-encryption-sdk-java](https://github.com/aws/aws-encryption-sdk-java/) repository on GitHub.

**Topics**
+ [Strings](#java-example-strings)
+ [Byte streams](#java-example-streams)
+ [Byte streams with multiple master key providers](#java-example-multiple-providers)

## Encrypting and decrypting strings
<a name="java-example-strings"></a>

The following example shows you how to use version 3.*x* of the AWS Encryption SDK for Java to encrypt and decrypt strings. Before using the string, convert it into a byte array.

This example uses an [AWS KMS keyring](use-kms-keyring.md). When you encrypt with an AWS KMS keyring, you can use a key ID, key ARN, alias name, or alias ARN to identify the KMS keys. When decrypting, you must use a key ARN to identify KMS keys.

When you call the `encryptData()` method, it returns an [encrypted message](concepts.md#message) (`CryptoResult`) that includes the ciphertext, the encrypted data keys, and the encryption context. When you call `getResult` on the `CryptoResult` object, it returns a base-64-encoded string version of the [encrypted message](message-format.md) that you can pass to the `decryptData()` method.

Similarly, when you call `decryptData()`, the `CryptoResult` object it returns contains the plaintext message and an AWS KMS key ID. Before your application returns the plaintext, verify that the AWS KMS key ID and the encryption context in the encrypted message are the ones that you expect.

```
// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

package com.amazonaws.crypto.keyrings;

import com.amazonaws.encryptionsdk.AwsCrypto;
import com.amazonaws.encryptionsdk.CommitmentPolicy;
import com.amazonaws.encryptionsdk.CryptoResult;
import software.amazon.cryptography.materialproviders.IKeyring;
import software.amazon.cryptography.materialproviders.MaterialProviders;
import software.amazon.cryptography.materialproviders.model.CreateAwsKmsMultiKeyringInput;
import software.amazon.cryptography.materialproviders.model.MaterialProvidersConfig;

import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;

/**
 * Encrypts and then decrypts data using an AWS KMS Keyring.
 *
 * <p>Arguments:
 *
 * <ol>
 *   <li>Key ARN: For help finding the Amazon Resource Name (ARN) of your AWS KMS customer master
 *       key (CMK), see 'Viewing Keys' at
 *       http://docs.aws.amazon.com/kms/latest/developerguide/viewing-keys.html
 * </ol>
 */
public class BasicEncryptionKeyringExample {

  private static final byte[] EXAMPLE_DATA = "Hello World".getBytes(StandardCharsets.UTF_8);

  public static void main(final String[] args) {
    final String keyArn = args[0];

    encryptAndDecryptWithKeyring(keyArn);
  }

  public static void encryptAndDecryptWithKeyring(final String keyArn) {
    // 1. Instantiate the SDK
    // This builds the AwsCrypto client with the RequireEncryptRequireDecrypt commitment policy,
    // which means this client only encrypts using committing algorithm suites and enforces
    // that the client will only decrypt encrypted messages that were created with a committing
    // algorithm suite.
    // This is the default commitment policy if you build the client with
    // `AwsCrypto.builder().build()`
    // or `AwsCrypto.standard()`.
    final AwsCrypto crypto =
        AwsCrypto.builder()
            .withCommitmentPolicy(CommitmentPolicy.RequireEncryptRequireDecrypt)
            .build();

    // 2. Create the AWS KMS keyring.
    // This example creates a multi keyring, which automatically creates the KMS client.
    final MaterialProviders materialProviders =
        MaterialProviders.builder()
            .MaterialProvidersConfig(MaterialProvidersConfig.builder().build())
            .build();
    final CreateAwsKmsMultiKeyringInput keyringInput =
        CreateAwsKmsMultiKeyringInput.builder().generator(keyArn).build();
    final IKeyring kmsKeyring = materialProviders.CreateAwsKmsMultiKeyring(keyringInput);

    // 3. Create an encryption context
    // We recommend using an encryption context whenever possible
    // to protect integrity. This sample uses placeholder values.
    // For more information see:
    // blogs.aws.amazon.com/security/post/Tx2LZ6WBJJANTNW/How-to-Protect-the-Integrity-of-Your-Encrypted-Data-by-Using-AWS-Key-Management
    final Map<String, String> encryptionContext =
        Collections.singletonMap("ExampleContextKey", "ExampleContextValue");

    // 4. Encrypt the data
    final CryptoResult<byte[], ?> encryptResult =
        crypto.encryptData(kmsKeyring, EXAMPLE_DATA, encryptionContext);
    final byte[] ciphertext = encryptResult.getResult();

    // 5. Decrypt the data
    final CryptoResult<byte[], ?> decryptResult =
        crypto.decryptData(
            kmsKeyring,
            ciphertext,
            // Verify that the encryption context in the result contains the
            // encryption context supplied to the encryptData method
            encryptionContext);

    // 6. Verify that the decrypted plaintext matches the original plaintext
    assert Arrays.equals(decryptResult.getResult(), EXAMPLE_DATA);
  }
}
```

## Encrypting and decrypting byte streams
<a name="java-example-streams"></a>

The following example shows you how to use the AWS Encryption SDK to encrypt and decrypt byte streams.

This example uses a [Raw AES keyring](use-raw-aes-keyring.md).

When encrypting, this example uses the `AwsCrypto.builder() .withEncryptionAlgorithm()` method to specify an algorithm suite without [digital signatures](concepts.md#digital-sigs). When decrypting, to ensure that the ciphertext is unsigned, this example uses the `createUnsignedMessageDecryptingStream()` method. The `createUnsignedMessageDecryptingStream()` method, fails if it encounters a ciphertext with a digital signature. 

If you're encrypting with the default algorithm suite, which includes digital signatures, use the `createDecryptingStream()` method instead, as shown in the next example.

```
// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

package com.amazonaws.crypto.keyrings;

import com.amazonaws.encryptionsdk.AwsCrypto;
import com.amazonaws.encryptionsdk.CommitmentPolicy;
import com.amazonaws.encryptionsdk.CryptoAlgorithm;
import com.amazonaws.encryptionsdk.CryptoInputStream;
import com.amazonaws.encryptionsdk.jce.JceMasterKey;
import com.amazonaws.util.IOUtils;
import software.amazon.cryptography.materialproviders.IKeyring;
import software.amazon.cryptography.materialproviders.MaterialProviders;
import software.amazon.cryptography.materialproviders.model.AesWrappingAlg;
import software.amazon.cryptography.materialproviders.model.CreateRawAesKeyringInput;
import software.amazon.cryptography.materialproviders.model.MaterialProvidersConfig;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.security.SecureRandom;
import java.util.Collections;
import java.util.Map;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;


/**
 * <p>
 * Encrypts and then decrypts a file under a random key.
 *
 * <p>
 * Arguments:
 * <ol>
 * <li>Name of file containing plaintext data to encrypt
 * </ol>
 *
 * <p>
 * This program demonstrates using a standard Java {@link SecretKey} object as a {@link IKeyring} to
 * encrypt and decrypt streaming data.
 */
public class FileStreamingKeyringExample {
    private static String srcFile;

    public static void main(String[] args) throws IOException {
        srcFile = args[0];

        // In this example, we generate a random key. In practice, 
        // you would get a key from an existing store
        SecretKey cryptoKey = retrieveEncryptionKey();

        // Create a Raw Aes Keyring using the random key and an AES-GCM encryption algorithm
        final MaterialProviders materialProviders = MaterialProviders.builder()
                .MaterialProvidersConfig(MaterialProvidersConfig.builder().build())
                .build();
        final CreateRawAesKeyringInput keyringInput = CreateRawAesKeyringInput.builder()
                .wrappingKey(ByteBuffer.wrap(cryptoKey.getEncoded()))
                .keyNamespace("Example")
                .keyName("RandomKey")
                .wrappingAlg(AesWrappingAlg.ALG_AES128_GCM_IV12_TAG16)
                .build();
        IKeyring keyring = materialProviders.CreateRawAesKeyring(keyringInput);

        // Instantiate the SDK.
        // This builds the AwsCrypto client with the RequireEncryptRequireDecrypt commitment policy,
        // which means this client only encrypts using committing algorithm suites and enforces
        // that the client will only decrypt encrypted messages that were created with a committing
        // algorithm suite.
        // This is the default commitment policy if you build the client with
        // `AwsCrypto.builder().build()`
        // or `AwsCrypto.standard()`.
        // This example encrypts with an algorithm suite that doesn't include signing for faster decryption,
        // since this use case assumes that the contexts that encrypt and decrypt are equally trusted.
        final AwsCrypto crypto = AwsCrypto.builder()
                .withCommitmentPolicy(CommitmentPolicy.RequireEncryptRequireDecrypt)
                .withEncryptionAlgorithm(CryptoAlgorithm.ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY)
                .build();

        // Create an encryption context to identify the ciphertext
        Map<String, String> context = Collections.singletonMap("Example", "FileStreaming");

        // Because the file might be too large to load into memory, we stream the data, instead of 
        //loading it all at once.
        FileInputStream in = new FileInputStream(srcFile);
        CryptoInputStream<JceMasterKey> encryptingStream = crypto.createEncryptingStream(keyring, in, context);

        FileOutputStream out = new FileOutputStream(srcFile + ".encrypted");
        IOUtils.copy(encryptingStream, out);
        encryptingStream.close();
        out.close();

        // Decrypt the file. Verify the encryption context before returning the plaintext.
        // Since the data was encrypted using an unsigned algorithm suite, use the recommended
        // createUnsignedMessageDecryptingStream method, which only accepts unsigned messages.
        in = new FileInputStream(srcFile + ".encrypted");
        CryptoInputStream<JceMasterKey> decryptingStream = crypto.createUnsignedMessageDecryptingStream(keyring, in);
        // Does it contain the expected encryption context?
        if (!"FileStreaming".equals(decryptingStream.getCryptoResult().getEncryptionContext().get("Example"))) {
            throw new IllegalStateException("Bad encryption context");
        }

        // Write the plaintext data to disk.
        out = new FileOutputStream(srcFile + ".decrypted");
        IOUtils.copy(decryptingStream, out);
        decryptingStream.close();
        out.close();
    }

    /**
     * In practice, this key would be saved in a secure location.
     * For this demo, we generate a new random key for each operation.
     */
    private static SecretKey retrieveEncryptionKey() {
        SecureRandom rnd = new SecureRandom();
        byte[] rawKey = new byte[16]; // 128 bits
        rnd.nextBytes(rawKey);
        return new SecretKeySpec(rawKey, "AES");
    }
}
```

## Encrypting and decrypting byte streams with a multi-keyring
<a name="java-example-multiple-providers"></a>

The following example shows you how to use the AWS Encryption SDK with a [multi-keyring](use-multi-keyring.md). When you use a multi-keyring to encrypt data, any of the wrapping keys in any of its keyrings can decrypt that data. This example uses an [AWS KMS keyring](use-kms-keyring.md) and a [Raw RSA keyring](use-raw-rsa-keyring.md) as the child keyrings.

This example encrypts with the [default algorithm suite](supported-algorithms.md), which includes a [digital signature](concepts.md#digital-sigs). When streaming, the AWS Encryption SDK releases plaintext after integrity checks, but before it has verified the digital signature. To avoid using the plaintext until the signature is verified, this example buffers the plaintext, and writes it to disk only when decryption and verification are complete. 

```
// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

package com.amazonaws.crypto.keyrings;

import com.amazonaws.encryptionsdk.AwsCrypto;
import com.amazonaws.encryptionsdk.CommitmentPolicy;
import com.amazonaws.encryptionsdk.CryptoOutputStream;
import com.amazonaws.util.IOUtils;
import software.amazon.cryptography.materialproviders.IKeyring;
import software.amazon.cryptography.materialproviders.MaterialProviders;
import software.amazon.cryptography.materialproviders.model.CreateAwsKmsMultiKeyringInput;
import software.amazon.cryptography.materialproviders.model.CreateMultiKeyringInput;
import software.amazon.cryptography.materialproviders.model.CreateRawRsaKeyringInput;
import software.amazon.cryptography.materialproviders.model.MaterialProvidersConfig;
import software.amazon.cryptography.materialproviders.model.PaddingScheme;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.security.GeneralSecurityException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.util.Collections;

/**
 * <p>
 * Encrypts a file using both AWS KMS Key and an asymmetric key pair.
 *
 * <p>
 * Arguments:
 * <ol>
 * <li>Key ARN: For help finding the Amazon Resource Name (ARN) of your AWS KMS key,
 *   see 'Viewing Keys' at http://docs.aws.amazon.com/kms/latest/developerguide/viewing-keys.html
 *
 * <li>Name of file containing plaintext data to encrypt
 * </ol>
 * <p>
 * You might use AWS Key Management Service (AWS KMS) for most encryption and decryption operations, but
 * still want the option of decrypting your data offline independently of AWS KMS. This sample
 * demonstrates one way to do this.
 * <p>
 * The sample encrypts data under both an AWS KMS key and an "escrowed" RSA key pair
 * so that either key alone can decrypt it. You might commonly use the AWS KMS key for decryption. However,
 * at any time, you can use the private RSA key to decrypt the ciphertext independent of AWS KMS.
 * <p>
 * This sample uses the RawRsaKeyring to generate a RSA public-private key pair
 * and saves the key pair in memory. In practice, you would store the private key in a secure offline
 * location, such as an offline HSM, and distribute the public key to your development team.
 */
public class EscrowedEncryptKeyringExample {
    private static ByteBuffer publicEscrowKey;
    private static ByteBuffer privateEscrowKey;

    public static void main(final String[] args) throws Exception {
        // This sample generates a new random key for each operation.
        // In practice, you would distribute the public key and save the private key in secure
        // storage.
        generateEscrowKeyPair();

        final String kmsArn = args[0];
        final String fileName = args[1];

        standardEncrypt(kmsArn, fileName);
        standardDecrypt(kmsArn, fileName);

        escrowDecrypt(fileName);
    }

    private static void standardEncrypt(final String kmsArn, final String fileName) throws Exception {
        // Encrypt with the KMS key and the escrowed public key
        // 1. Instantiate the SDK
        // This builds the AwsCrypto client with the RequireEncryptRequireDecrypt commitment policy,
        // which means this client only encrypts using committing algorithm suites and enforces
        // that the client will only decrypt encrypted messages that were created with a committing
        // algorithm suite.
        // This is the default commitment policy if you build the client with
        // `AwsCrypto.builder().build()`
        // or `AwsCrypto.standard()`.
        final AwsCrypto crypto = AwsCrypto.builder()
                .withCommitmentPolicy(CommitmentPolicy.RequireEncryptRequireDecrypt)
                .build();

        // 2. Create the AWS KMS keyring.
        // This example creates a multi keyring, which automatically creates the KMS client.
        final MaterialProviders matProv = MaterialProviders.builder()
                .MaterialProvidersConfig(MaterialProvidersConfig.builder().build())
                .build();
        final CreateAwsKmsMultiKeyringInput keyringInput = CreateAwsKmsMultiKeyringInput.builder()
                .generator(kmsArn)
                .build();
        IKeyring kmsKeyring = matProv.CreateAwsKmsMultiKeyring(keyringInput);

        // 3. Create the Raw Rsa Keyring with Public Key.
        final CreateRawRsaKeyringInput encryptingKeyringInput = CreateRawRsaKeyringInput.builder()
                .keyName("Escrow")
                .keyNamespace("Escrow")
                .paddingScheme(PaddingScheme.OAEP_SHA512_MGF1)
                .publicKey(publicEscrowKey)
                .build();
        IKeyring rsaPublicKeyring = matProv.CreateRawRsaKeyring(encryptingKeyringInput);

        // 4. Create the multi-keyring.
        final CreateMultiKeyringInput createMultiKeyringInput = CreateMultiKeyringInput.builder()
                .generator(kmsKeyring)
                .childKeyrings(Collections.singletonList(rsaPublicKeyring))
                .build();
        IKeyring multiKeyring = matProv.CreateMultiKeyring(createMultiKeyringInput);

        // 5. Encrypt the file
        // To simplify this code example, we omit the encryption context. Production code should always 
        // use an encryption context. 
        final FileInputStream in = new FileInputStream(fileName);
        final FileOutputStream out = new FileOutputStream(fileName + ".encrypted");
        final CryptoOutputStream<?> encryptingStream = crypto.createEncryptingStream(multiKeyring, out);

        IOUtils.copy(in, encryptingStream);
        in.close();
        encryptingStream.close();
    }

    private static void standardDecrypt(final String kmsArn, final String fileName) throws Exception {
        // Decrypt with the AWS KMS key and the escrow public key. 

        // 1. Instantiate the SDK.
        // This builds the AwsCrypto client with the RequireEncryptRequireDecrypt commitment policy,
        // which means this client only encrypts using committing algorithm suites and enforces
        // that the client will only decrypt encrypted messages that were created with a committing
        // algorithm suite.
        // This is the default commitment policy if you build the client with
        // `AwsCrypto.builder().build()`
        // or `AwsCrypto.standard()`.
        final AwsCrypto crypto = AwsCrypto.builder()
                .withCommitmentPolicy(CommitmentPolicy.RequireEncryptRequireDecrypt)
                .build();

        // 2. Create the AWS KMS keyring.
        // This example creates a multi keyring, which automatically creates the KMS client.
        final MaterialProviders matProv = MaterialProviders.builder()
                .MaterialProvidersConfig(MaterialProvidersConfig.builder().build())
                .build();
        final CreateAwsKmsMultiKeyringInput keyringInput = CreateAwsKmsMultiKeyringInput.builder()
                .generator(kmsArn)
                .build();
        IKeyring kmsKeyring = matProv.CreateAwsKmsMultiKeyring(keyringInput);

        // 3. Create the Raw Rsa Keyring with Public Key.
        final CreateRawRsaKeyringInput encryptingKeyringInput = CreateRawRsaKeyringInput.builder()
                .keyName("Escrow")
                .keyNamespace("Escrow")
                .paddingScheme(PaddingScheme.OAEP_SHA512_MGF1)
                .publicKey(publicEscrowKey)
                .build();
        IKeyring rsaPublicKeyring = matProv.CreateRawRsaKeyring(encryptingKeyringInput);

        // 4. Create the multi-keyring.
        final CreateMultiKeyringInput createMultiKeyringInput = CreateMultiKeyringInput.builder()
                .generator(kmsKeyring)
                .childKeyrings(Collections.singletonList(rsaPublicKeyring))
                .build();
        IKeyring multiKeyring = matProv.CreateMultiKeyring(createMultiKeyringInput);

        // 5. Decrypt the file
        // To simplify this code example, we omit the encryption context. Production code should always 
        // use an encryption context. 
        final FileInputStream in = new FileInputStream(fileName + ".encrypted");
        final FileOutputStream out = new FileOutputStream(fileName + ".decrypted");
        // Since we are using a signing algorithm suite, we avoid streaming decryption directly to the output file,
        // to ensure that the trailing signature is verified before writing any untrusted plaintext to disk.
        final ByteArrayOutputStream plaintextBuffer = new ByteArrayOutputStream();
        final CryptoOutputStream<?> decryptingStream = crypto.createDecryptingStream(multiKeyring, plaintextBuffer);
        IOUtils.copy(in, decryptingStream);
        in.close();
        decryptingStream.close();
        final ByteArrayInputStream plaintextReader = new ByteArrayInputStream(plaintextBuffer.toByteArray());
        IOUtils.copy(plaintextReader, out);
        out.close();
    }

    private static void escrowDecrypt(final String fileName) throws Exception {
        // You can decrypt the stream using only the private key.
        // This method does not call AWS KMS.

        // 1. Instantiate the SDK
        final AwsCrypto crypto = AwsCrypto.standard();

        // 2. Create the Raw Rsa Keyring with Private Key.
        final MaterialProviders matProv = MaterialProviders.builder()
                .MaterialProvidersConfig(MaterialProvidersConfig.builder().build())
                .build();
        final CreateRawRsaKeyringInput encryptingKeyringInput = CreateRawRsaKeyringInput.builder()
                .keyName("Escrow")
                .keyNamespace("Escrow")
                .paddingScheme(PaddingScheme.OAEP_SHA512_MGF1)
                .publicKey(publicEscrowKey)
                .privateKey(privateEscrowKey)
                .build();
        IKeyring escrowPrivateKeyring = matProv.CreateRawRsaKeyring(encryptingKeyringInput);


        // 3. Decrypt the file
        // To simplify this code example, we omit the encryption context. Production code should always 
        // use an encryption context. 
        final FileInputStream in = new FileInputStream(fileName + ".encrypted");
        final FileOutputStream out = new FileOutputStream(fileName + ".deescrowed");
        final CryptoOutputStream<?> decryptingStream = crypto.createDecryptingStream(escrowPrivateKeyring, out);
        IOUtils.copy(in, decryptingStream);
        in.close();
        decryptingStream.close();

    }

    private static void generateEscrowKeyPair() throws GeneralSecurityException {
        final KeyPairGenerator kg = KeyPairGenerator.getInstance("RSA");
        kg.initialize(4096); // Escrow keys should be very strong
        final KeyPair keyPair = kg.generateKeyPair();
        publicEscrowKey = RawRsaKeyringExample.getPEMPublicKey(keyPair.getPublic());
        privateEscrowKey = RawRsaKeyringExample.getPEMPrivateKey(keyPair.getPrivate());

    }
}
```

# AWS Encryption SDK for JavaScript
<a name="javascript"></a>

The AWS Encryption SDK for JavaScript is designed to provide a client-side encryption library for developers who are writing web browser applications in JavaScript or web server applications in Node.js.

Like all implementations of the AWS Encryption SDK, the AWS Encryption SDK for JavaScript offers advanced data protection features. These include [envelope encryption](concepts.md#envelope-encryption), additional authenticated data (AAD), and secure, authenticated, symmetric key [algorithm suites](concepts.md#crypto-algorithm), such as 256-bit AES-GCM with key derivation and signing.

All language-specific implementations of the AWS Encryption SDK are designed to be interoperable, subject to the constraints of the language. For details about language constraints for JavaScript, see [Compatibility of the AWS Encryption SDK for JavaScript](javascript-compatibility.md).

**Learn More**
+ For details about programming with the AWS Encryption SDK for JavaScript, see the [aws-encryption-sdk-javascript](https://github.com/aws/aws-encryption-sdk-javascript/) repository on GitHub.
+ For programming examples, see [AWS Encryption SDK for JavaScript examples](js-examples.md) and the [example-browser](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/example-browser) and [example-node](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/example-node) modules in the [aws-encryption-sdk-javascript](https://github.com/aws/aws-encryption-sdk-javascript/) repository. 
+  For a real-world example of using the AWS Encryption SDK for JavaScript to encrypt data in a web application, see [How to enable encryption in a browser with the AWS Encryption SDK for JavaScript and Node.js](https://aws.amazon.com/blogs/security/how-to-enable-encryption-browser-aws-encryption-sdk-javascript-node-js/) in the AWS Security Blog.

**Topics**
+ [Compatibility](javascript-compatibility.md)
+ [Installation](javascript-installation.md)
+ [Modules](javascript-modules.md)
+ [Examples](js-examples.md)

# Compatibility of the AWS Encryption SDK for JavaScript
<a name="javascript-compatibility"></a>

The AWS Encryption SDK for JavaScript is designed to be interoperable with other language implementations of the AWS Encryption SDK. In most cases, you can encrypt data with the AWS Encryption SDK for JavaScript and decrypt it with any other language implementation, including the [AWS Encryption SDK Command Line Interface](crypto-cli.md). And you can use the AWS Encryption SDK for JavaScript to decrypt [encrypted messages](concepts.md#message) produced by other language implementations of the AWS Encryption SDK.

However, when you use the AWS Encryption SDK for JavaScript, you need to be aware of some compatibility issues in the JavaScript language implementation and in web browsers.

Also, when using different language implementations, be sure to configure compatible master key providers, master keys, and keyrings. For details, see [Keyring compatibility](choose-keyring.md#keyring-compatibility).

## AWS Encryption SDK for JavaScript compatibility
<a name="javascript-language-compatibility"></a>

The JavaScript implementation of the AWS Encryption SDK differs from other language implementations in the following ways:
+ The encrypt operation of the AWS Encryption SDK for JavaScript doesn't return nonframed ciphertext. However, the AWS Encryption SDK for JavaScript will decrypt framed and nonframed ciphertext returned by other language implementations of the AWS Encryption SDK.
+ Beginning in Node.js version 12.9.0, Node.js supports the following RSA key wrapping options:
  + OAEP with SHA1, SHA256, SHA384, or SHA512
  + OAEP with SHA1 and MGF1 with SHA1
  + PKCS1v15
+ Before version 12.9.0, Node.js supports only the following RSA key wrapping options:
  + OAEP with SHA1 and MGF1 with SHA1
  + PKCS1v15

## Browser compatibility
<a name="javascript-browser-compatibility"></a>

Some web browsers don't support basic cryptographic operations that the AWS Encryption SDK for JavaScript requires. You can compensate for some of the missing operations by configuring a fallback for the WebCrypto API that the browser implements.

**Web browser limitations**

The following limitations are common to all web browsers:
+ The WebCrypto API doesn't support PKCS1v15 key wrapping.
+ Browsers don't support 192-bit keys.

**Required cryptographic operations**

The AWS Encryption SDK for JavaScript requires the following operations in web browsers. If a browser doesn't support these operations, it's incompatible with the AWS Encryption SDK for JavaScript.
+ The browser must include `crypto.getRandomValues()`, which is a method for generating cryptographically random values. For information about the web browser versions that support `crypto.getRandomValues()`, see [Can I Use crypto.getRandomValues()?](https://caniuse.com/#feat=getrandomvalues).

**Required fallback**

The AWS Encryption SDK for JavaScript requires the following libraries and operations in web browsers. If you support a web browser that doesn't fulfill these requirements, you must configure a fallback. Otherwise, attempts to use the AWS Encryption SDK for JavaScript with the browser will fail.
+ The WebCrypto API, which performs basic cryptographic operations in web applications, isn't available for all browsers. For information about the web browser versions that support web cryptography, see [Can I Use Web Cryptography?](https://caniuse.com/#feat=cryptography).
+ Modern versions of the Safari web browser don't support AES-GCM encryption of zero bytes, which the AWS Encryption SDK requires. If the browser implements the WebCrypto API, but can't use AES-GCM to encrypt zero bytes, the AWS Encryption SDK for JavaScript uses the fallback library only for zero-byte encryption. It uses the WebCrypto API for all other operations.

To configure a fallback for either limitation, add the following statements to your code. In the [configureFallback](https://github.com/aws/aws-encryption-sdk-javascript/blob/master/modules/web-crypto-backend/src/backend-factory.ts#L78) function, specify a library that supports the missing features. The following example uses the Microsoft Research JavaScript Cryptography Library (`msrcrypto`), but you can replace it with a compatible library. For a complete example, see [fallback.ts](https://github.com/aws/aws-encryption-sdk-javascript/blob/master/modules/example-browser/src/fallback.ts).

```
import { configureFallback } from '@aws-crypto/client-browser'
configureFallback(msrCrypto)
```

# Installing the AWS Encryption SDK for JavaScript
<a name="javascript-installation"></a>

The AWS Encryption SDK for JavaScript consists of a collection of interdependent modules. Several of the modules are just collections of modules that are designed to work together. Some modules are designed to work independently. A few modules are required for all implementations; a few others are required only for special cases. For information about the modules in the AWS Encryption SDK for JavaScript, see [Modules in the AWS Encryption SDK for JavaScript](javascript-modules.md) and the `README.md` file in each of the modules in the [aws-encryption-sdk-javascript](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules) repository on GitHub.

**Note**  
All versions of the AWS Encryption SDK for JavaScript earlier than 2.0.0 are in the [end-of-support phase](https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html#version-life-cycle).  
You can safely update from version 2.0.*x* and later to the latest version of the AWS Encryption SDK for JavaScript without any code or data changes. However, [ new security features](about-versions.md#version-2) introduced in version 2.0.*x* are not backward-compatible. To update from versions earlier than 1.7.*x* to version 2.0.*x* and later, you must first update to the latest 1.*x* version of the AWS Encryption SDK for JavaScript. For details, see [Migrating your AWS Encryption SDK](migration.md).

To install the modules, use the [npm package manager](https://www.npmjs.com/get-npm). 

For example, to install the `client-node` module, which includes all of the modules you need to program with the AWS Encryption SDK for JavaScript in Node.js, use the following command. 

```
npm install @aws-crypto/client-node
```

To install the `client-browser` module, which includes all of the modules you need to program with the AWS Encryption SDK for JavaScript in the browser, use the following command. 

```
npm install @aws-crypto/client-browser
```

For working examples of how to use the AWS Encryption SDK for JavaScript, see the examples in the `example-node` and `example-browser` modules in the [aws-encryption-sdk-javascript](https://github.com/aws/aws-encryption-sdk-javascript/) repository on GitHub.

# Modules in the AWS Encryption SDK for JavaScript
<a name="javascript-modules"></a>

The modules in the AWS Encryption SDK for JavaScript make it easy to install the code that you need for your projects.

## Modules for JavaScript Node.js
<a name="jsn-modules-node"></a>

[client-node](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/client-node)  
Includes all of the modules you need to program with the AWS Encryption SDK for JavaScript in Node.js.

[caching-materials-manager-node](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/caching-materials-manager-node)  
Exports functions that support the [data key caching](data-key-caching.md) feature in the AWS Encryption SDK for JavaScript in Node.js. 

[decrypt-node](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/decrypt-node)  
Exports functions that decrypt and verify encrypted messages representing data and data streams. Included in the `client-node` module.

[encrypt-node](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/encrypt-node)  
Exports functions that encrypt and sign different types of data. Included in the `client-node` module.

[example-node](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/example-node)  
Exports working examples of programming with the AWS Encryption SDK for JavaScript in Node.js. Includes example of different types of keyrings and different types of data.

[hkdf-node](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/hkdf-node)  
Exports an [HMAC-based Key Derivation Function](https://en.wikipedia.org/wiki/HKDF) (HKDF) that the AWS Encryption SDK for JavaScript in Node.js uses in particular algorithm suites. The AWS Encryption SDK for JavaScript in the browser uses the native HKDF function in the WebCrypto API.

[integration-node](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/integration-node)  
Defines tests that verify that the AWS Encryption SDK for JavaScript in Node.js is compatible with other language implementations of the AWS Encryption SDK.

[kms-keyring-node](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/kms-keyring-node)  
Exports functions that support AWS KMS keyrings in Node.js.

[raw-aes-keyring-node](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/raw-aes-keyring-node)  
Exports functions that support [Raw AES keyrings](use-raw-aes-keyring.md) in Node.js.

[raw-rsa-keyring-node](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/raw-rsa-keyring-node)  
Exports functions that support [Raw RSA keyrings](use-raw-rsa-keyring.md) in Node.js.

## Modules for JavaScript Browser
<a name="jsn-modules-browser"></a>

[client-browser](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/client-browser)  
Includes all of the modules you need to program with the AWS Encryption SDK for JavaScript in the browser.

[caching-materials-manager-browser](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/caching-materials-manager-browser)  
Exports functions that support the [data key caching](data-key-caching.md) feature for JavaScript in the browser.

[decrypt-browser](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/decrypt-browser)  
Exports functions that decrypt and verify encrypted messages representing data and data streams.

[encrypt-browser](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/encrypt-browser)  
Exports functions that encrypt and sign different types of data. 

[example-browser](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/example-browser)  
Working examples of programming with the AWS Encryption SDK for JavaScript in the browser. Includes examples of different types of keyrings and different types of data.

[integration-browser](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/integration-browser)  
Defines tests that verify that the AWS Encryption SDK for JavaScript in the browser is compatible with other language implementations of the AWS Encryption SDK.

[kms-keyring-browser](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/kms-keyring-browser)  
Exports functions that support [AWS KMS keyrings](use-kms-keyring.md) in the browser.

[raw-aes-keyring-browser](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/raw-aes-keyring-browser)  
Exports functions that support [Raw AES keyrings](use-raw-aes-keyring.md) in the browser.

[raw-rsa-keyring-browser](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/raw-rsa-keyring-browser)  
Exports functions that support [Raw RSA keyrings](use-raw-rsa-keyring.md) in the browser.

## Modules for all implementations
<a name="jsn-modules-all"></a>

[cache-material](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/cache-material)  
Supports the [data key caching](data-key-caching.md) feature. Provides code for assembling the cryptographic materials that are cached with each data key.

[kms-keyring](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/kms-keyring)  
Exports functions that support [KMS keyrings](use-kms-keyring.md).

[material-management](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/material-management)  
Implements the [cryptographic materials manager](concepts.md#crypt-materials-manager) (CMM).

[raw-keyring](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/raw-keyring)  
Exports functions required for raw AES and RSA keyrings.

[serialize](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/serialize)  
Exports functions that the SDK uses to serialize its output.

[web-crypto-backend](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/web-crypto-backend)  
Exports functions that use the WebCrypto API in the AWS Encryption SDK for JavaScript in the browser.

# AWS Encryption SDK for JavaScript examples
<a name="js-examples"></a>

The following examples show you how to use the AWS Encryption SDK for JavaScript to encrypt and decrypt data. 

You can find more examples of using the AWS Encryption SDK for JavaScript in the [example-node](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/example-node) and [example-browser](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/example-browser) modules in the [aws-encryption-sdk-javascript](https://github.com/aws/aws-encryption-sdk-javascript/) repository on GitHub. These example modules are not installed when you install the `client-browser` or `client-node` modules.

**See the complete code samples**: Node: [kms\$1simple.ts](https://github.com/aws/aws-encryption-sdk-javascript/blob/master/modules/example-node/src/kms_simple.ts), Browser: [kms\$1simple.ts](https://github.com/aws/aws-encryption-sdk-javascript/blob/master/modules/example-browser/src/kms_simple.ts)

**Topics**
+ [

## Encrypting data with an AWS KMS keyring
](#javascript-example-encrypt)
+ [

## Decrypting data with an AWS KMS keyring
](#javascript-example-decrypt)

## Encrypting data with an AWS KMS keyring
<a name="javascript-example-encrypt"></a>

The following example shows you how to use the AWS Encryption SDK for JavaScript to encrypt and decrypt a short string or byte array. 

This example features an [AWS KMS keyring](use-kms-keyring.md), a type of keyring that uses an AWS KMS key to generate and encrypt data keys. For help creating an AWS KMS key, see [Creating Keys](https://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html) in the *AWS Key Management Service Developer Guide*. For help identifying the AWS KMS keys in an AWS KMS keyring, see [Identifying AWS KMS keys in an AWS KMS keyring](use-kms-keyring.md#kms-keyring-id)

Step 1: Set the commitment policy.  
Beginning in version 1.7.*x* of the AWS Encryption SDK for JavaScript, you can set the commitment policy when you call the new `buildClient` function that instantiates an AWS Encryption SDK client. The `buildClient` function takes an enumerated value that represents your commitment policy. It returns updated `encrypt` and `decrypt` functions that enforce your commitment policy when you encrypt and decrypt.  
The following examples use the `buildClient` function to specify the [default commitment policy](migrate-commitment-policy.md), `REQUIRE_ENCRYPT_REQUIRE_DECRYPT`. You can also use the `buildClient` to limit the number of encrypted data keys in an encrypted message. For more information, see [Limiting encrypted data keys](configure.md#config-limit-keys).  

```
import {
  KmsKeyringBrowser,
  KMS,
  getClient,
  buildClient,
  CommitmentPolicy,
} from '@aws-crypto/client-browser'

const { encrypt, decrypt } = buildClient(
  CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT
)
```

```
import {
  KmsKeyringNode,
  buildClient,
  CommitmentPolicy,
} from '@aws-crypto/client-node'
                                
const { encrypt, decrypt } = buildClient(
  CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT
)
```

Step 2: Construct the keyring.  
Create an AWS KMS keyring for encryption.   
When encrypting with an AWS KMS keyring, you must specify a *generator key*, that is, an AWS KMS key that is used to generate the plaintext data key and encrypt it. You can also specify zero or more *additional keys* that encrypt the same plaintext data key. The keyring returns the plaintext data key and one encrypted copy of that data key for each AWS KMS key in the keyring, including the generator key. To decrypt the data, you need to decrypt any one of the encrypted data keys.  
To specify the AWS KMS keys for an encryption keyring in the AWS Encryption SDK for JavaScript, you can use [any supported AWS KMS key identifier](use-kms-keyring.md#kms-keyring-id). This example uses a generator key, which is identified by its [alias ARN](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id-alias-ARN), and one additional key, which is identified by a [key ARN](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id-key-ARN).  
If you plan to reuse your AWS KMS keyring for decrypting, you must use key ARNs to identify the AWS KMS keys in the keyring.
Before running this code, replace the example AWS KMS key identifiers with valid identifiers. You must have the [permissions required to use the AWS KMS keys](use-kms-keyring.md#kms-keyring-permissions) in the keyring.  
Begin by providing your credentials to the browser. The AWS Encryption SDK for JavaScript examples use the [webpack.DefinePlugin](https://webpack.js.org/plugins/define-plugin/), which replaces the credential constants with your actual credentials. But you can use any method to provide your credentials. Then, use the credentials to create an AWS KMS client.  

```
declare const credentials: {accessKeyId: string, secretAccessKey:string, sessionToken:string }

const clientProvider = getClient(KMS, {
  credentials: {
    accessKeyId,
    secretAccessKey,
    sessionToken
  }
})
```
Next, specify the AWS KMS keys for the generator key and additional key. Then, create an AWS KMS keyring using the AWS KMS client and the AWS KMS keys.  

```
const generatorKeyId = 'arn:aws:kms:us-west-2:111122223333:alias/EncryptDecrypt'
const keyIds = ['arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab']

const keyring = new KmsKeyringBrowser({ clientProvider, generatorKeyId, keyIds })
```

```
const generatorKeyId = 'arn:aws:kms:us-west-2:111122223333:alias/EncryptDecrypt'
const keyIds = ['arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab']

const keyring = new KmsKeyringNode({ generatorKeyId, keyIds })
```

Step 3: Set the encryption context.  
An [encryption context](concepts.md#encryption-context) is arbitrary, non-secret additional authenticated data. When you provide an encryption context on encrypt, the AWS Encryption SDK cryptographically binds the encryption context to the ciphertext so that the same encryption context is required to decrypt the data. Using an encryption context is optional, but we recommend it as a best practice.  
Create a simple object that includes the encryption context pairs. The key and value in each pair must be a string.  

```
const context = {
  stage: 'demo',
  purpose: 'simple demonstration app',
  origin: 'us-west-2'
}
```

```
const context = {
  stage: 'demo',
  purpose: 'simple demonstration app',
  origin: 'us-west-2'
}
```

Step 4: Encrypt the data.  
To encrypt the plaintext data, call the `encrypt` function. Pass in the AWS KMS keyring, the plaintext data, and the encryption context.  
The `encrypt` function returns an [encrypted message](concepts.md#message) (`result`) that contains the encrypted data, the encrypted data keys, and important metadata, including the encryption context and signature.  
You can [decrypt this encrypted message](#javascript-example-decrypt) by using the AWS Encryption SDK for any supported programming language.  

```
const plaintext = new Uint8Array([1, 2, 3, 4, 5])

const { result } = await encrypt(keyring, plaintext, { encryptionContext: context })
```

```
const plaintext = 'asdf'

const { result } = await encrypt(keyring, plaintext, { encryptionContext: context })
```

## Decrypting data with an AWS KMS keyring
<a name="javascript-example-decrypt"></a>

You can use the AWS Encryption SDK for JavaScript to decrypt the encrypted message and recover the original data.

In this example, we decrypt the data that we encrypted in the [Encrypting data with an AWS KMS keyring](#javascript-example-encrypt) example.

Step 1: Set the commitment policy.  
Beginning in version 1.7.*x* of the AWS Encryption SDK for JavaScript, you can set the commitment policy when you call the new `buildClient` function that instantiates an AWS Encryption SDK client. The `buildClient` function takes an enumerated value that represents your commitment policy. It returns updated `encrypt` and `decrypt` functions that enforce your commitment policy when you encrypt and decrypt.  
The following examples use the `buildClient` function to specify the [default commitment policy](migrate-commitment-policy.md), `REQUIRE_ENCRYPT_REQUIRE_DECRYPT`. You can also use the `buildClient` to limit the number of encrypted data keys in an encrypted message. For more information, see [Limiting encrypted data keys](configure.md#config-limit-keys).  

```
import {
  KmsKeyringBrowser,
  KMS,
  getClient,
  buildClient,
  CommitmentPolicy,
} from '@aws-crypto/client-browser'

const { encrypt, decrypt } = buildClient(
  CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT
)
```

```
import {
  KmsKeyringNode,
  buildClient,
  CommitmentPolicy,
} from '@aws-crypto/client-node'
                                
const { encrypt, decrypt } = buildClient(
  CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT
)
```

Step 2: Construct the keyring.  
To decrypt the data, pass in the [encrypted message](concepts.md#message) (`result`) that the `encrypt` function returned. The encrypted message includes the encrypted data, the encrypted data keys, and important metadata, including the encryption context and signature.  
You must also specify an [AWS KMS keyring](use-kms-keyring.md) when decrypting. You can use the same keyring that was used to encrypt the data or a different keyring. To succeed, at least one AWS KMS key in the decryption keyring must be able to decrypt one of the encrypted data keys in the encrypted message. Because no data keys are generated, you do not need to specify a generator key in a decryption keyring. If you do, the generator key and additional keys are treated the same way.  
To specify an AWS KMS key for a decryption keyring in the AWS Encryption SDK for JavaScript, you must use the [key ARN](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id-key-ARN). Otherwise, the AWS KMS key is not recognized. For help identifying the AWS KMS keys in an AWS KMS keyring, see [Identifying AWS KMS keys in an AWS KMS keyring](use-kms-keyring.md#kms-keyring-id)  
If you use the same keyring for encrypting and decrypting, use key ARNs to identify the AWS KMS keys in the keyring.
In this example, we create a keyring that includes only one of the AWS KMS keys in the encryption keyring. Before running this code, replace the example key ARN with a valid one. You must have `kms:Decrypt` permission on the AWS KMS key.  
Begin by providing your credentials to the browser. The AWS Encryption SDK for JavaScript examples use the [webpack.DefinePlugin](https://webpack.js.org/plugins/define-plugin/), which replaces the credential constants with your actual credentials. But you can use any method to provide your credentials. Then, use the credentials to create an AWS KMS client.  

```
declare const credentials: {accessKeyId: string, secretAccessKey:string, sessionToken:string }

const clientProvider = getClient(KMS, {
  credentials: {
    accessKeyId,
    secretAccessKey,
    sessionToken
  }
})
```
Next, create an AWS KMS keyring using the AWS KMS client. This example uses just one of the AWS KMS keys from the encryption keyring.  

```
const keyIds = ['arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab']

const keyring = new KmsKeyringBrowser({ clientProvider, keyIds })
```

```
const keyIds = ['arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab']

const keyring = new KmsKeyringNode({ keyIds })
```

Step 3: Decrypt the data.  
Next, call the `decrypt` function. Pass in the decryption keyring that you just created (`keyring`) and the [encrypted message](concepts.md#message) that the `encrypt` function returned (`result`). The AWS Encryption SDK uses the keyring to decrypt one of the encrypted data keys. Then it uses the plaintext data key to decrypt the data.  
If the call succeeds, the `plaintext` field contains the plaintext (decrypted) data. The `messageHeader` field contains metadata about the decryption process, including the encryption context that was used to decrypt the data.  

```
const { plaintext, messageHeader } = await decrypt(keyring, result)
```

```
const { plaintext, messageHeader } = await decrypt(keyring, result)
```

Step 4: Verify the encryption context.  
The [encryption context](concepts.md#encryption-context) that was used to decrypt the data is included in the message header (`messageHeader`) that the `decrypt` function returns. Before your application returns the plaintext data, verify that the encryption context that you provided when encrypting is included in the encryption context that was used when decrypting. A mismatch might indicate that the data was tampered with, or that you didn't decrypt the right ciphertext.  
When verifying the encryption context, do not require an exact match. When you use an encryption algorithm with signing, the [cryptographic materials manager](concepts.md#crypt-materials-manager) (CMM) adds the public signing key to the encryption context before encrypting the message. But all of the encryption context pairs that you submitted should be included in the encryption context that was returned.  
First, get the encryption context from the message header. Then, verify that each key-value pair in the original encryption context (`context`) matches a key-value pair in the returned encryption context (`encryptionContext`).  

```
const { encryptionContext } = messageHeader

Object
  .entries(context)
  .forEach(([key, value]) => {
    if (encryptionContext[key] !== value) throw new Error('Encryption Context does not match expected values')
})
```

```
const { encryptionContext } = messageHeader

Object
  .entries(context)
  .forEach(([key, value]) => {
    if (encryptionContext[key] !== value) throw new Error('Encryption Context does not match expected values')
})
```
If the encryption context check succeeds, you can return the plaintext data.

# AWS Encryption SDK for Python
<a name="python"></a>

This topic explains how to install and use the AWS Encryption SDK for Python. For details about programming with the AWS Encryption SDK for Python, see the [aws-encryption-sdk-python](https://github.com/aws/aws-encryption-sdk-python/) repository on GitHub. For API documentation, see [Read the Docs](https://aws-encryption-sdk-python.readthedocs.io/en/latest/).

**Topics**
+ [

## Prerequisites
](#python-prerequisites)
+ [

## Installation
](#python-installation)
+ [Examples](python-example-code.md)

## Prerequisites
<a name="python-prerequisites"></a>

Before you install the AWS Encryption SDK for Python, be sure you have the following prerequisites.

**A supported version of Python**  
Python 3.8 or later is required by the AWS Encryption SDK for Python versions 3.2.0 and later.  
The [AWS Cryptographic Material Providers Library](https://github.com/aws/aws-cryptographic-material-providers-library) (MPL) is an optional dependency for the AWS Encryption SDK for Python introduced in version 4.*x*. If you intend to install the MPL, you must use Python 3.11 or later.
Earlier versions of the AWS Encryption SDK support Python 2.7 and Python 3.4 and later, but we recommend that you use the latest version of the AWS Encryption SDK.   
To download Python, see [Python downloads](https://www.python.org/downloads/).

**The pip installation tool for Python**  
`pip` is included in Python 3.6 and later versions, although you might want to upgrade it. For more information about upgrading or installing `pip`, see [Installation](https://pip.pypa.io/en/latest/installation/) in the `pip` documentation.

## Installation
<a name="python-installation"></a>

Install the latest version of the AWS Encryption SDK for Python.

**Note**  
All versions of the AWS Encryption SDK for Python earlier than 3.0.0 are in the [end-of-support phase](https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html#version-life-cycle).  
You can safely update from version 2.0.*x* and later to the latest version of the AWS Encryption SDK without any code or data changes. However, [ new security features](about-versions.md#version-2) introduced in version 2.0.*x* are not backward-compatible. To update from versions earlier than 1.7.*x* to version 2.0.*x* and later, you must first update to the latest 1.*x* version of the AWS Encryption SDK. For details, see [Migrating your AWS Encryption SDK](migration.md).

Use `pip` to install the AWS Encryption SDK for Python, as shown in the following examples.

**To install the latest version**  

```
pip install "aws-encryption-sdk[MPL]"
```
The `[MPL]` suffix installs the [AWS Cryptographic Material Providers Library](https://github.com/aws/aws-cryptographic-material-providers-library) (MPL). The MPL contains constructs for encrypting and decrypting your data. The MPL is an optional dependency for the AWS Encryption SDK for Python introduced in version 4.*x*. We highly recommend installing the MPL. However, if you do not intend to use the MPL, you can omit the `[MPL]` suffix.

For more details about using pip to install and upgrade packages, see [Installing Packages](https://packaging.python.org/tutorials/installing-packages/).

The AWS Encryption SDK for Python requires the [cryptography library](https://cryptography.io/en/latest/) (pyca/cryptography) on all platforms. All versions of `pip` automatically install and build the `cryptography` library on Windows. `pip` 8.1 and later automatically installs and builds `cryptography` on Linux. If you are using an earlier version of `pip` and your Linux environment doesn't have the tools needed to build the `cryptography` library, you need to install them. For more information, see [Building Cryptography on Linux](https://cryptography.io/en/latest/installation.html#building-cryptography-on-linux).

Versions 1.10.0 and 2.5.0 of the AWS Encryption SDK for Python pin the [cryptography](https://cryptography.io/en/latest/) dependency between 2.5.0 and 3.3.2. Other versions of the AWS Encryption SDK for Python install the latest version of cryptography. If you require a version of cryptography later than 3.3.2, we recommend that you use the latest major version of the AWS Encryption SDK for Python.

For the latest development version of the AWS Encryption SDK for Python, go to the [aws-encryption-sdk-python](https://github.com/aws/aws-encryption-sdk-python/) repository in GitHub.

After you install the AWS Encryption SDK for Python, get started by looking at the [Python example code](python-example-code.md) in this guide.

# AWS Encryption SDK for Python example code
<a name="python-example-code"></a>

The following examples show you how to use the AWS Encryption SDK for Python to encrypt and decrypt data.

The examples in this section show how to use version 4.*x* of the AWS Encryption SDK for Python with the optional [Cryptographic Material Providers Library](https://github.com/aws/aws-cryptographic-material-providers-library) dependency (`aws-cryptographic-material-providers`). To view examples that use earlier versions, or installations without the material providers library (MPL), find your release in the [Releases](https://github.com/aws/aws-encryption-sdk-python/releases) list of the [aws-encryption-sdk-python](https://github.com/aws/aws-encryption-sdk-python/) repository on GitHub.

When you use version 4.*x* of the AWS Encryption SDK for Python with the MPL, it uses [keyrings](choose-keyring.md) to perform [envelope encryption](concepts.md#envelope-encryption). The AWS Encryption SDK provides keyrings that are compatible with the master key providers that you used in previous versions. For more information, see [Keyring compatibility](choose-keyring.md#keyring-compatibility). For examples on migrating from master key providers to keyrings, see [Migration Examples](https://github.com/aws/aws-encryption-sdk-python/tree/master/examples/src/migration) in the `aws-encryption-sdk-python` repository on GitHub;

**Topics**
+ [Strings](#python-example-strings)
+ [Byte streams](#python-example-streams)

## Encrypting and decrypting strings
<a name="python-example-strings"></a>

The following example shows you how to use the AWS Encryption SDK to encrypt and decrypt strings. This example uses an [AWS KMS keyring](use-kms-keyring.md) with a symmetric encryption KMS key.

This example instantiates the AWS Encryption SDK client with the [default commitment policy](migrate-commitment-policy.md), `REQUIRE_ENCRYPT_REQUIRE_DECRYPT`. For more information, see [Setting your commitment policy](migrate-commitment-policy.md).

```
# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
"""
This example sets up the KMS Keyring

The AWS KMS keyring uses symmetric encryption KMS keys to generate, encrypt and
decrypt data keys. This example creates a KMS Keyring and then encrypts a custom input EXAMPLE_DATA
with an encryption context. This example also includes some sanity checks for demonstration:
1. Ciphertext and plaintext data are not the same
2. Encryption context is correct in the decrypted message header
3. Decrypted plaintext value matches EXAMPLE_DATA
These sanity checks are for demonstration in the example only. You do not need these in your code.

AWS KMS keyrings can be used independently or in a multi-keyring with other keyrings
of the same or a different type.

"""

import boto3
from aws_cryptographic_material_providers.mpl import AwsCryptographicMaterialProviders
from aws_cryptographic_material_providers.mpl.config import MaterialProvidersConfig
from aws_cryptographic_material_providers.mpl.models import CreateAwsKmsKeyringInput
from aws_cryptographic_material_providers.mpl.references import IKeyring
from typing import Dict  # noqa pylint: disable=wrong-import-order

import aws_encryption_sdk
from aws_encryption_sdk import CommitmentPolicy

EXAMPLE_DATA: bytes = b"Hello World"


def encrypt_and_decrypt_with_keyring(
    kms_key_id: str
):
    """Demonstrate an encrypt/decrypt cycle using an AWS KMS keyring.

    Usage: encrypt_and_decrypt_with_keyring(kms_key_id)
    :param kms_key_id: KMS Key identifier for the KMS key you want to use for encryption and
    decryption of your data keys.
    :type kms_key_id: string
    
    """
    # 1. Instantiate the encryption SDK client.
    # This builds the client with the REQUIRE_ENCRYPT_REQUIRE_DECRYPT commitment policy,
    # which enforces that this client only encrypts using committing algorithm suites and enforces
    # that this client will only decrypt encrypted messages that were created with a committing
    # algorithm suite.
    # This is the default commitment policy if you were to build the client as
    # `client = aws_encryption_sdk.EncryptionSDKClient()`.
    client = aws_encryption_sdk.EncryptionSDKClient(
        commitment_policy=CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT
    )

    # 2. Create a boto3 client for KMS.
    kms_client = boto3.client('kms', region_name="us-west-2")

    # 3. Optional: create encryption context.
    # Remember that your encryption context is NOT SECRET.
    encryption_context: Dict[str, str] = {
        "encryption": "context",
        "is not": "secret",
        "but adds": "useful metadata",
        "that can help you": "be confident that",
        "the data you are handling": "is what you think it is",
    }

    # 4. Create your keyring
    mat_prov: AwsCryptographicMaterialProviders = AwsCryptographicMaterialProviders(
        config=MaterialProvidersConfig()
    )

    keyring_input: CreateAwsKmsKeyringInput = CreateAwsKmsKeyringInput(
        kms_key_id=kms_key_id,
        kms_client=kms_client
    )

    kms_keyring: IKeyring = mat_prov.create_aws_kms_keyring(
        input=keyring_input
    )

    # 5. Encrypt the data with the encryptionContext.
    ciphertext, _ = client.encrypt(
        source=EXAMPLE_DATA,
        keyring=kms_keyring,
        encryption_context=encryption_context
    )

    # 6. Demonstrate that the ciphertext and plaintext are different.
    # (This is an example for demonstration; you do not need to do this in your own code.)
    assert ciphertext != EXAMPLE_DATA, \
        "Ciphertext and plaintext data are the same. Invalid encryption"

    # 7. Decrypt your encrypted data using the same keyring you used on encrypt.
    plaintext_bytes, _ = client.decrypt(
        source=ciphertext,
        keyring=kms_keyring,
        # Provide the encryption context that was supplied to the encrypt method
        encryption_context=encryption_context,
    )

    # 8. Demonstrate that the decrypted plaintext is identical to the original plaintext.
    # (This is an example for demonstration; you do not need to do this in your own code.)
    assert plaintext_bytes == EXAMPLE_DATA, \
        "Decrypted plaintext should be identical to the original plaintext. Invalid decryption"
```

## Encrypting and decrypting byte streams
<a name="python-example-streams"></a>

The following example shows you how to use the AWS Encryption SDK to encrypt and decrypt byte streams. This example uses a [Raw AES keyring](use-raw-aes-keyring.md).

This example instantiates the AWS Encryption SDK client with the [default commitment policy](migrate-commitment-policy.md), `REQUIRE_ENCRYPT_REQUIRE_DECRYPT`. For more information, see [Setting your commitment policy](migrate-commitment-policy.md).

```
# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
"""
This example demonstrates file streaming for encryption and decryption.

File streaming is useful when the plaintext or ciphertext file/data is too large to load into
memory. Therefore, the AWS Encryption SDK allows users to stream the data, instead of loading it
all at once in memory. In this example, we demonstrate file streaming for encryption and decryption
using a Raw AES keyring. However, you can use any keyring with streaming.

This example creates a Raw AES Keyring and then encrypts an input stream from the file
`plaintext_filename` with an encryption context to an output (encrypted) file `ciphertext_filename`.
It then decrypts the ciphertext from `ciphertext_filename` to a new file `decrypted_filename`.
This example also includes some sanity checks for demonstration:
1. Ciphertext and plaintext data are not the same
2. Encryption context is correct in the decrypted message header
3. Decrypted plaintext value matches EXAMPLE_DATA
These sanity checks are for demonstration in the example only. You do not need these in your code.

See raw_aes_keyring_example.py in the same directory for another raw AES keyring example
in the AWS Encryption SDK for Python.
"""
import filecmp
import secrets

from aws_cryptographic_material_providers.mpl import AwsCryptographicMaterialProviders
from aws_cryptographic_material_providers.mpl.config import MaterialProvidersConfig
from aws_cryptographic_material_providers.mpl.models import AesWrappingAlg, CreateRawAesKeyringInput
from aws_cryptographic_material_providers.mpl.references import IKeyring
from typing import Dict  # noqa pylint: disable=wrong-import-order

import aws_encryption_sdk
from aws_encryption_sdk import CommitmentPolicy


def encrypt_and_decrypt_with_keyring(
    plaintext_filename: str,
    ciphertext_filename: str,
    decrypted_filename: str
):
    """Demonstrate a streaming encrypt/decrypt cycle.

    Usage: encrypt_and_decrypt_with_keyring(plaintext_filename
                                            ciphertext_filename
                                            decrypted_filename)
    :param plaintext_filename: filename of the plaintext data
    :type plaintext_filename: string
    :param ciphertext_filename: filename of the ciphertext data
    :type ciphertext_filename: string
    :param decrypted_filename: filename of the decrypted data
    :type decrypted_filename: string
    """
    # 1. Instantiate the encryption SDK client.
    # This builds the client with the REQUIRE_ENCRYPT_REQUIRE_DECRYPT commitment policy,
    # which enforces that this client only encrypts using committing algorithm suites and enforces
    # that this client will only decrypt encrypted messages that were created with a committing
    # algorithm suite.
    # This is the default commitment policy if you were to build the client as
    # `client = aws_encryption_sdk.EncryptionSDKClient()`.
    client = aws_encryption_sdk.EncryptionSDKClient(
        commitment_policy=CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT
    )

    # 2. The key namespace and key name are defined by you.
    # and are used by the Raw AES keyring to determine
    # whether it should attempt to decrypt an encrypted data key.
    key_name_space = "Some managed raw keys"
    key_name = "My 256-bit AES wrapping key"

    # 3. Optional: create encryption context.
    # Remember that your encryption context is NOT SECRET.
    encryption_context: Dict[str, str] = {
        "encryption": "context",
        "is not": "secret",
        "but adds": "useful metadata",
        "that can help you": "be confident that",
        "the data you are handling": "is what you think it is",
    }

    # 4. Generate a 256-bit AES key to use with your keyring.
    # In practice, you should get this key from a secure key management system such as an HSM.

    # Here, the input to secrets.token_bytes() = 32 bytes = 256 bits
    static_key = secrets.token_bytes(32)

    # 5. Create a Raw AES keyring
    # We choose to use a raw AES keyring, but any keyring can be used with streaming.
    mat_prov: AwsCryptographicMaterialProviders = AwsCryptographicMaterialProviders(
        config=MaterialProvidersConfig()
    )

    keyring_input: CreateRawAesKeyringInput = CreateRawAesKeyringInput(
        key_namespace=key_name_space,
        key_name=key_name,
        wrapping_key=static_key,
        wrapping_alg=AesWrappingAlg.ALG_AES256_GCM_IV12_TAG16
    )

    raw_aes_keyring: IKeyring = mat_prov.create_raw_aes_keyring(
        input=keyring_input
    )

    # 6. Encrypt the data stream with the encryptionContext
    with open(plaintext_filename, 'rb') as pt_file, open(ciphertext_filename, 'wb') as ct_file:
        with client.stream(
            mode='e',
            source=pt_file,
            keyring=raw_aes_keyring,
            encryption_context=encryption_context
        ) as encryptor:
            for chunk in encryptor:
                ct_file.write(chunk)

    # 7. Demonstrate that the ciphertext and plaintext are different.
    # (This is an example for demonstration; you do not need to do this in your own code.)
    assert not filecmp.cmp(plaintext_filename, ciphertext_filename), \
        "Ciphertext and plaintext data are the same. Invalid encryption"

    # 8. Decrypt your encrypted data stream using the same keyring you used on encrypt.
    with open(ciphertext_filename, 'rb') as ct_file, open(decrypted_filename, 'wb') as pt_file:
        with client.stream(
            mode='d',
            source=ct_file,
            keyring=raw_aes_keyring,
            encryption_context=encryption_context
        ) as decryptor:
            for chunk in decryptor:
                pt_file.write(chunk)

    # 10. Demonstrate that the decrypted plaintext is identical to the original plaintext.
    # (This is an example for demonstration; you do not need to do this in your own code.)
    assert filecmp.cmp(plaintext_filename, decrypted_filename), \
        "Decrypted plaintext should be identical to the original plaintext. Invalid decryption"
```

# AWS Encryption SDK for Rust
<a name="rust"></a>

This topic explains how to install and use the AWS Encryption SDK for Rust. For details about programming with the AWS Encryption SDK for Rust, see the [Rust](https://github.com/aws/aws-encryption-sdk-dafny/tree/mainline/AwsEncryptionSDK/runtimes/rust/) directory of the aws-encryption-sdk repository on GitHub.

The AWS Encryption SDK for Rust differs from some of the other programming language implementations of the AWS Encryption SDK in the following ways:
+ No support for [data key caching](data-key-caching.md). However, the AWS Encryption SDK for Rust supports the [AWS KMS Hierarchical keyring](use-hierarchical-keyring.md), an alternative cryptographic materials caching solution.
+ No support for streaming data

The AWS Encryption SDK for Rust includes all of the security features introduced in versions 2.0.*x* and later of other language implementations of the AWS Encryption SDK. However, if you are using the AWS Encryption SDK for Rust to decrypt data that was encrypted by a pre-2.0.*x* version another language implementation of the AWS Encryption SDK, you might need to adjust your [commitment policy](concepts.md#commitment-policy). For details, see [How to set your commitment policy](migrate-commitment-policy.md#migrate-commitment-step1).

The AWS Encryption SDK for Rust is a product of the AWS Encryption SDK in [Dafny](https://github.com/dafny-lang/dafny/blob/master/README.md), a formal verification language in which you write specifications, the code to implement them, and the proofs to test them. The result is a library that implements the features of the AWS Encryption SDK in a framework that assures functional correctness.

**Learn More**
+ For examples showing how to configure options in the AWS Encryption SDK, such as specifying an alternate algorithm suite, limiting encrypted data keys, and using AWS KMS multi-Region keys, see [Configuring the AWS Encryption SDK](configure.md).
+ For examples showing how to configure and use the AWS Encryption SDK for Rust, see the [Rust examples](https://github.com/aws/aws-encryption-sdk-dafny/tree/mainline/AwsEncryptionSDK/runtimes/rust/examples) in the aws-encryption-sdk repository on GitHub.

**Topics**
+ [

## Prerequisites
](#prerequisites-rust)
+ [

## Installation
](#rust-installation)
+ [Examples](rust-examples.md)

## Prerequisites
<a name="prerequisites-rust"></a>

Before you install the AWS Encryption SDK for Rust, be sure you have the following prerequisites.

**Install Rust and Cargo**  
Install the current stable release of [Rust](https://www.rust-lang.org/) using [rustup](https://rustup.rs/).  
For more information on downloading and installing rustup, see the [installation procedures](https://doc.rust-lang.org/cargo/getting-started/installation.html) in The Cargo Book.

## Installation
<a name="rust-installation"></a>

The AWS Encryption SDK for Rust is available as the [https://crates.io/crates/aws-esdk](https://crates.io/crates/aws-esdk) crate on Crates.io. For details on installing and building the AWS Encryption SDK for Rust, see the [README.md](https://github.com/aws/aws-encryption-sdk/tree/mainline) in the aws-encryption-sdk repository on GitHub.

You can install the AWS Encryption SDK for Rust in the following ways.

**Manually**  
To install the AWS Encryption SDK for Rust, clone or download the [aws-encryption-sdk](https://github.com/aws/aws-encryption-sdk/tree/mainline) GitHub repository.

**Using Crates.io**  
Run the following Cargo command in your project directory:  

```
cargo add aws-esdk
```
Or add the following line to your Cargo.toml:  

```
aws-esdk = "<version>"
```

# AWS Encryption SDK for Rust example code
<a name="rust-examples"></a>

The following examples show the basic coding patterns that you use when programming with the AWS Encryption SDK for Rust. Specifically, you instantiate the AWS Encryption SDK and the material providers library. Then, before calling each method, you instantiate the object that defines the input for the method.

For examples showing how to configure options in the AWS Encryption SDK, such as specifying an alternate algorithm suite and limiting encrypted data keys, see the [Rust examples](https://github.com/aws/aws-encryption-sdk-dafny/tree/mainline/AwsEncryptionSDK/runtimes/rust/examples/) in the aws-encryption-sdk repository on GitHub.

## Encrypting and decrypting data in the AWS Encryption SDK for Rust
<a name="rust-example-encrypt"></a>

This example shows the basic pattern for encrypting and decrypting data. It encrypts a small file with data keys that are protected by one AWS KMS wrapping key.

**Step 1: Instantiate the AWS Encryption SDK.**  
You'll use the methods in the AWS Encryption SDK to encrypt and decrypt data.  

```
let esdk_config = AwsEncryptionSdkConfig::builder().build()?;
let esdk_client = esdk_client::Client::from_conf(esdk_config)?;
```

**Step 2: Create an AWS KMS client.**  

```
let sdk_config = aws_config::load_defaults(aws_config::BehaviorVersion::latest()).await;
let kms_client = aws_sdk_kms::Client::new(&sdk_config);
```

**Optional: Create your encryption context.**  

```
let encryption_context = HashMap::from([
    ("encryption".to_string(), "context".to_string()),
    ("is not".to_string(), "secret".to_string()),
    ("but adds".to_string(), "useful metadata".to_string()),
    ("that can help you".to_string(), "be confident that".to_string()),
    ("the data you are handling".to_string(), "is what you think it is".to_string()),
]);
```

**Step 3: Instantiate the material providers library.**  
You'll use the methods in the material providers library to create the keyrings that specify which keys protect your data.  

```
let mpl_config = MaterialProvidersConfig::builder().build()?;
let mpl = mpl_client::Client::from_conf(mpl_config)?;
```

**Step 4: Create an AWS KMS keyring.**  
To create the keyring, call the keyring method with the keyring input object. This example uses the `create_aws_kms_keyring()` method and specifies one KMS key.  

```
let kms_keyring = mpl
    .create_aws_kms_keyring()
    .kms_key_id(kms_key_id)
    .kms_client(kms_client)
    .send()
    .await?;
```

**Step 5: Encrypt the plaintext.**  

```
let plaintext = example_data.as_bytes();

let encryption_response = esdk_client.encrypt()
    .plaintext(plaintext)
    .keyring(kms_keyring.clone())
    .encryption_context(encryption_context.clone())
    .send()
    .await?;

let ciphertext = encryption_response
                    .ciphertext
                    .expect("Unable to unwrap ciphertext from encryption response");
```

**Step 6: Decrypt your encrypted data using the same keyring you used on encrypt.**  

```
let decryption_response = esdk_client.decrypt()
    .ciphertext(ciphertext)
    .keyring(kms_keyring)
    // Provide the encryption context that was supplied to the encrypt method
    .encryption_context(encryption_context)
    .send()
    .await?;

let decrypted_plaintext = decryption_response
                            .plaintext
                            .expect("Unable to unwrap plaintext from decryption response");
```

# AWS Encryption SDK command line interface
<a name="crypto-cli"></a>

The AWS Encryption SDK Command Line Interface (AWS Encryption CLI) enables you to use the AWS Encryption SDK to encrypt and decrypt data interactively at the command line and in scripts. You don't need cryptography or programming expertise.

**Note**  
Versions of the AWS Encryption CLI earlier than 4.0.0 are in the [end-of-support phase](https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html#version-life-cycle).  
You can safely update from version 2.1.*x* and later to the latest version of the AWS Encryption CLI without any code or data changes. However, [ new security features](about-versions.md#version-2) introduced in version 2.1.*x* are not backward-compatible. To update from version 1.7.*x* or earlier, you must first update to the latest 1.*x* version of the AWS Encryption CLI. For details, see [Migrating your AWS Encryption SDK](migration.md).  
New security features were originally released in AWS Encryption CLI versions 1.7.*x* and 2.0.*x*. However, AWS Encryption CLI version 1.8.*x* replaces version 1.7.*x* and AWS Encryption CLI 2.1.*x* replaces 2.0.*x*. For details, see the relevant [security advisory](https://github.com/aws/aws-encryption-sdk-cli/security/advisories/GHSA-2xwp-m7mq-7q3r) in the [aws-encryption-sdk-cli](https://github.com/aws/aws-encryption-sdk-cli/) repository on GitHub.

Like all implementations of the AWS Encryption SDK, the AWS Encryption CLI offers advanced data protection features. These include [envelope encryption](https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/how-it-works.html#envelope-encryption), additional authenticated data (AAD), and secure, authenticated, symmetric key [algorithm suites](https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/supported-algorithms.html), such as 256-bit AES-GCM with key derivation, [key commitment](concepts.md#key-commitment), and signing. 

The AWS Encryption CLI is built on the [AWS Encryption SDK for Python](python.md) and is supported on Linux, macOS, and Windows. You can run commands and scripts to encrypt and decrypt your data in your preferred shell on Linux or macOS, in a Command Prompt window (cmd.exe) on Windows, and in a PowerShell console on any system. 

All language-specific implementations of the AWS Encryption SDK, including the AWS Encryption CLI, are interoperable. For example, you can encrypt data with the [AWS Encryption SDK for Java](java.md) and decrypt it with the AWS Encryption CLI. 

This topic introduces the AWS Encryption CLI, explains how to install and use it, and provides several examples to help you get started. For a quick start, see [How to Encrypt and Decrypt Your Data with the AWS Encryption CLI](https://aws.amazon.com/blogs/security/how-to-encrypt-and-decrypt-your-data-with-the-aws-encryption-cli/) in the AWS Security Blog. For more detailed information, see [Read The Docs](https://aws-encryption-sdk-cli.readthedocs.io/en/latest/), and join us in developing the AWS Encryption CLI in the [aws-encryption-sdk-cli](https://github.com/aws/aws-encryption-sdk-cli/) repository on GitHub.

**Performance**  
The AWS Encryption CLI is built on the AWS Encryption SDK for Python. Each time you run the CLI, you start a new instance of the Python runtime. To improve performance, whenever possible, use a single command instead of a series of independent commands. For example, run one command that processes the files in a directory recursively instead of running separate commands for each file.

**Topics**
+ [Installing the CLI](crypto-cli-install.md)
+ [How to use the CLI](crypto-cli-how-to.md)
+ [Examples](crypto-cli-examples.md)
+ [Syntax and parameter reference](crypto-cli-reference.md)
+ [Versions](crypto-cli-versions.md)

# Installing the AWS Encryption SDK command line interface
<a name="crypto-cli-install"></a>

This topic explains how to install the AWS Encryption CLI. For detailed information, see the [aws-encryption-sdk-cli](https://github.com/aws/aws-encryption-sdk-cli/) repository on GitHub and [Read the Docs](https://aws-encryption-sdk-cli.readthedocs.io/en/latest/).

**Topics**
+ [

## Installing the prerequisites
](#crypto-cli-prerequisites)
+ [Installing the CLI](#install-sdk-cli)

## Installing the prerequisites
<a name="crypto-cli-prerequisites"></a>

The AWS Encryption CLI is built on the AWS Encryption SDK for Python. To install the AWS Encryption CLI, you need Python and `pip`, the Python package management tool. Python and `pip` are available on all supported platforms.

Install the following prerequisites before you install the AWS Encryption CLI, 

**Python**  
Python 3.8 or later is required by the AWS Encryption CLI versions 4.2.0 and later.  
Earlier versions of the AWS Encryption CLI support Python 2.7 and 3.4 and later, but we recommend that you use the latest version of the AWS Encryption CLI.  
Python is included in most Linux and macOS installations, but you need to upgrade to Python 3.6 or later. We recommend that you use the latest version of Python. On Windows, you have to install Python; it is not installed by default. To download and install Python, see [Python downloads](https://www.python.org/downloads/).  
To determine whether Python is installed, at the command line, type the following.  

```
python
```
To check the Python version, use the `-V` (uppercase V) parameter.  

```
python -V
```
On Windows, after you install Python, add the path to the `Python.exe` file to the value of the **Path** environment variable.   
By default, Python is installed in the all users directory or in a user profile directory (`$home` or `%userprofile%`) in the `AppData\Local\Programs\Python` subdirectory. To find the location of the `Python.exe` file on your system, check one of the following registry keys. You can use PowerShell to search the registry.   

```
PS C:\> dir HKLM:\Software\Python\PythonCore\version\InstallPath
# -or-
PS C:\> dir HKCU:\Software\Python\PythonCore\version\InstallPath
```

**pip**  
`pip` is the Python package manager. To install the AWS Encryption CLI and its dependencies, you need `pip` 8.1 or later. For help installing or upgrading `pip`, see [Installation](https://pip.pypa.io/en/latest/installing/) in the `pip` documentation.  
On Linux installations, versions of `pip` earlier than 8.1 can't build the **cryptography** library that the AWS Encryption CLI requires. If you choose not to update your `pip` version, you can install the build tools separately. For more information, see [Building cryptography on Linux](https://cryptography.io/en/latest/installation.html#building-cryptography-on-linux).

**AWS Command Line Interface**  
The AWS Command Line Interface (AWS CLI) is required only if you are using AWS KMS keys in AWS Key Management Service (AWS KMS) with the AWS Encryption CLI. If you are using a different [master key provider](concepts.md#master-key-provider), the AWS CLI is not required.  
To use AWS KMS keys with the AWS Encryption CLI, you need to [install](https://docs.aws.amazon.com/cli/latest/userguide/installing.html) and [configure ](http://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html#cli-quick-configuration) the AWS CLI. The configuration makes the credentials that you use to authenticate to AWS KMS available to the AWS Encryption CLI. 

## Installing and updating the AWS Encryption CLI
<a name="install-sdk-cli"></a>

Install the latest version of the AWS Encryption CLI. When you use `pip` to install the AWS Encryption CLI, it automatically installs the libraries that the CLI needs, including the [AWS Encryption SDK for Python](python.md), the Python [cryptography library](https://cryptography.io/en/latest/), and the [AWS SDK for Python (Boto3)](https://boto3.amazonaws.com/v1/documentation/api/latest/index.html).

**Note**  
Versions of the AWS Encryption CLI earlier than 4.0.0 are in the [end-of-support phase](https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html#version-life-cycle).  
You can safely update from version 2.1.*x* and later to the latest version of the AWS Encryption CLI without any code or data changes. However, [ new security features](about-versions.md#version-2) introduced in version 2.1.*x* are not backward-compatible. To update from version 1.7.*x* or earlier, you must first update to the latest 1.*x* version of the AWS Encryption CLI. For details, see [Migrating your AWS Encryption SDK](migration.md).  
New security features were originally released in AWS Encryption CLI versions 1.7.*x* and 2.0.*x*. However, AWS Encryption CLI version 1.8.*x* replaces version 1.7.*x* and AWS Encryption CLI 2.1.*x* replaces 2.0.*x*. For details, see the relevant [security advisory](https://github.com/aws/aws-encryption-sdk-cli/security/advisories/GHSA-2xwp-m7mq-7q3r) in the [aws-encryption-sdk-cli](https://github.com/aws/aws-encryption-sdk-cli/) repository on GitHub.

**To install the latest version of the AWS Encryption CLI**  

```
pip install aws-encryption-sdk-cli
```

**To upgrade to the latest version of the AWS Encryption CLI**  

```
pip install --upgrade aws-encryption-sdk-cli
```

**To find the version numbers of your AWS Encryption CLI and AWS Encryption SDK**  

```
aws-encryption-cli --version
```
The output lists the version numbers of both libraries.  

```
aws-encryption-sdk-cli/2.1.0 aws-encryption-sdk/2.0.0
```

**To upgrade to the latest version of the AWS Encryption CLI**  

```
pip install --upgrade aws-encryption-sdk-cli
```

Installing the AWS Encryption CLI also installs the latest version of the AWS SDK for Python (Boto3), if it's not already installed. If Boto3 is installed, the installer verifies the Boto3 version and updates it if required.

**To find your installed version of Boto3**  

```
pip show boto3
```

**To update to the latest version of Boto3**  

```
pip install --upgrade boto3
```

To install the version of the AWS Encryption CLI currently in development, see the [aws-encryption-sdk-cli](https://github.com/aws/aws-encryption-sdk-cli/) repository on GitHub.

For more details about using `pip` to install and upgrade Python packages, see the [pip documentation](https://pip.pypa.io/en/stable/quickstart/).

# How to use the AWS Encryption CLI
<a name="crypto-cli-how-to"></a>

This topic explains how to use the parameters in the AWS Encryption CLI. For examples, see [Examples of the AWS Encryption CLI](crypto-cli-examples.md). For complete documentation, see [Read the Docs](https://aws-encryption-sdk-cli.readthedocs.io/en/latest/). The syntax shown in these examples is for AWS Encryption CLI version 2.1.*x* and later.

**Note**  
Versions of the AWS Encryption CLI earlier than 4.0.0 are in the [end-of-support phase](https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html#version-life-cycle).  
You can safely update from version 2.1.*x* and later to the latest version of the AWS Encryption CLI without any code or data changes. However, [ new security features](about-versions.md#version-2) introduced in version 2.1.*x* are not backward-compatible. To update from version 1.7.*x* or earlier, you must first update to the latest 1.*x* version of the AWS Encryption CLI. For details, see [Migrating your AWS Encryption SDK](migration.md).  
New security features were originally released in AWS Encryption CLI versions 1.7.*x* and 2.0.*x*. However, AWS Encryption CLI version 1.8.*x* replaces version 1.7.*x* and AWS Encryption CLI 2.1.*x* replaces 2.0.*x*. For details, see the relevant [security advisory](https://github.com/aws/aws-encryption-sdk-cli/security/advisories/GHSA-2xwp-m7mq-7q3r) in the [aws-encryption-sdk-cli](https://github.com/aws/aws-encryption-sdk-cli/) repository on GitHub.

For an example showing how to use the security feature that limits encrypted data keys, see [Limiting encrypted data keys](configure.md#config-limit-keys).

For an example showing how to use AWS KMS multi-Region keys, see [Using multi-Region AWS KMS keys](configure.md#config-mrks).

**Topics**
+ [

## How to encrypt and decrypt data
](#crypto-cli-e-d-intro)
+ [

## How to specify wrapping keys
](#crypto-cli-master-key)
+ [

## How to provide input
](#crypto-cli-input)
+ [

## How to specify the output location
](#crypto-cli-output)
+ [

## How to use an encryption context
](#crypto-cli-encryption-context)
+ [

## How to specify a commitment policy
](#crypto-cli-commitment-policy)
+ [

## How to store parameters in a configuration file
](#crypto-cli-config-file)

## How to encrypt and decrypt data
<a name="crypto-cli-e-d-intro"></a>

The AWS Encryption CLI uses the features of the AWS Encryption SDK to make it easy to encrypt and decrypt data securely.

**Note**  
The `--master-keys` parameter is deprecated in version 1.8.*x* of the AWS Encryption CLI and removed in version 2.1.*x*. Instead, use the `--wrapping-keys` parameter. Beginning in version 2.1.*x*, the `--wrapping-keys` parameter is required when encrypting and decrypting. For details, see [AWS Encryption SDK CLI syntax and parameter reference](crypto-cli-reference.md).
+ When you encrypt data in the AWS Encryption CLI, you specify your plaintext data and a [wrapping key](concepts.md#master-key) (or *master key*), such as an AWS KMS key in AWS Key Management Service (AWS KMS). If you are using a custom master key provider, you also need to specify the provider. You also specify output locations for the [encrypted message](concepts.md#message) and for metadata about the encryption operation. An [encryption context](concepts.md#encryption-context) is optional, but recommended.

  In version 1.8.*x*, the `--commitment-policy` parameter is required when you use the `--wrapping-keys` parameter; otherwise it's not valid. Beginning in version 2.1.*x*, the `--commitment-policy` parameter is optional, but recommended.

  ```
  aws-encryption-cli --encrypt --input myPlaintextData \
                     --wrapping-keys key=1234abcd-12ab-34cd-56ef-1234567890ab \
                     --output myEncryptedMessage \
                     --metadata-output ~/metadata \
                     --encryption-context purpose=test \
                     --commitment-policy require-encrypt-require-decrypt
  ```

  The AWS Encryption CLI encrypts your data under a unique data key. Then it encrypts the data key under the wrapping keys you specify. It returns an [encrypted message](concepts.md#message) and metadata about the operation. The encrypted message contains your encrypted data (*ciphertext*) and an encrypted copy of the data key. You don't have to worry about storing, managing, or losing the data key.

   
+ When you decrypt data, you pass in your encrypted message, the optional encryption context, and location for the plaintext output and the metadata. You also specify the wrapping keys that the AWS Encryption CLI can use to decrypt the message, or tell the AWS Encryption CLI it can use any wrapping keys that encrypted the message.

  Beginning in version 1.8.*x*, the `--wrapping-keys` parameter is optional when decrypting, but recommended. Beginning in version 2.1.*x*, the `--wrapping-keys` parameter is required when encrypting and decrypting.

  When decrypting, you can use the **key** attribute of the `--wrapping-keys` parameter to specify the wrapping keys that decrypt your data. Specifying an AWS KMS wrapping key when decrypting is optional, but it's a [best practice](best-practices.md) that prevents you from using a key you didn't intend to use. If you're using a custom master key provider, you must specify the provider and wrapping key.

  If you don't use the **key** attribute, you must set the [**discovery** attribute](#discovery-cli-attribute) of the `--wrapping-keys` parameter to `true`, which lets the AWS Encryption CLI decrypt using any wrapping key that encrypted the message. 

  As a best practice, use the `--max-encrypted-data-keys` parameter to avoid decrypting a malformed message with an excessive number of encrypted data keys. Specify the expected number of encrypted data keys (one for each wrapping key used in encryption) or a reasonable maximum (such as 5). For details, see [Limiting encrypted data keys](configure.md#config-limit-keys).

  The `--buffer` parameter returns plaintext only after all input is processed, including verifying the digital signature if one is present. 

  The `--decrypt-unsigned` parameter decrypts ciphertext and ensures that messages are unsigned before decryption. Use this parameter if you used the `--algorithm` parameter and selected an algorithm suite without digital signing to encrypt data. If the ciphertext is signed, decryption fails.

  You can use `--decrypt` or `--decrypt-unsigned` for decryption but not both.

  ```
  aws-encryption-cli --decrypt --input myEncryptedMessage \
                     --wrapping-keys key=1234abcd-12ab-34cd-56ef-1234567890ab \
                     --output myPlaintextData \
                     --metadata-output ~/metadata \
                     --max-encrypted-data-keys 1 \
                     --buffer \
                     --encryption-context purpose=test \ 
                     --commitment-policy require-encrypt-require-decrypt
  ```

  The AWS Encryption CLI uses the wrapping key to decrypt the data key in the encrypted message. Then it uses the data key to decrypt your data. It returns your plaintext data and metadata about the operation.

## How to specify wrapping keys
<a name="crypto-cli-master-key"></a>

When you encrypt data in the AWS Encryption CLI, you need to specify at least one [wrapping key](concepts.md#master-key) (or *master key*). You can use AWS KMS keys in AWS Key Management Service (AWS KMS), wrapping keys from a custom [master key provider](concepts.md#master-key-provider), or both. The custom master key provider can be any compatible Python master key provider.

To specify wrapping keys in versions 1.8.*x* and later, use the `--wrapping-keys` parameter (`-w`). The value of this parameter is a collection of [attributes](#cli-master-key-attributes) with the `attribute=value` format. The attributes that you use depend on the master key provider and the command.
+ **AWS KMS**. In encrypt commands, you must specify a `--wrapping-keys` parameter with a **key** attribute. Beginning in version 2.1.*x*, the `--wrapping-keys` parameter is also required in decrypt commands. When decrypting, the `--wrapping-keys` parameter must have a **key** attribute or a **discovery** attribute with a value of `true` (but not both). Other attributes are optional.
+ **Custom master key provider**. You must specify a `--wrapping-keys` parameter in every command. The parameter value must have **key** and **provider** attributes.

You can include [multiple `--wrapping-keys` parameters](#cli-many-cmks) and multiple **key** attributes in the same command. 

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

The value of the `--wrapping-keys` parameter consists of the following attributes and their values. A `--wrapping-keys` parameter (or `--master-keys` parameter) is required in all encrypt commands. Beginning in version 2.1.*x*, the `--wrapping-keys` parameter is also required when decrypting.

If an attribute name or value includes spaces or special characters, enclose both the name and value in quotation marks. For example, `--wrapping-keys key=12345 "provider=my cool provider"`.

**Key: Specify a wrapping key**  
Use the **key** attribute to identify a wrapping key. When encrypting, the value can be any key identifier that the master key provider recognizes.   

```
--wrapping-keys key=1234abcd-12ab-34cd-56ef-1234567890ab
```
In an encrypt command, you must include at least one **key** attribute and value. To encrypt your data key under multiple wrapping keys, use [multiple **key** attributes](#cli-many-cmks).  

```
aws-encryption-cli --encrypt --wrapping-keys key=1234abcd-12ab-34cd-56ef-1234567890ab key=1a2b3c4d-5e6f-1a2b-3c4d-5e6f1a2b3c4d
```
In encrypt commands that use AWS KMS keys, the value of **key** can be the key ID, its key ARN, an alias name, or alias ARN. For example, this encrypt command uses an alias ARN in the value of the **key** attribute. For details about the key identifiers for an AWS KMS key, see [Key Identifiers](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id) in the *AWS Key Management Service Developer Guide*.  

```
aws-encryption-cli --encrypt --wrapping-keys key=arn:aws:kms:us-west-2:111122223333:alias/ExampleAlias
```
In decrypt commands that use a custom master key provider, **key** and **provider** attributes are required.  

```
\\ Custom master key provider
aws-encryption-cli --decrypt --wrapping-keys provider='myProvider' key='100101'
```
In decrypt commands that use AWS KMS, you can use the **key** attribute to specify the AWS KMS keys to use for decrypting, or the [**discovery** attribute](#discovery-cli-attribute) with a value of `true`, which lets the AWS Encryption CLI use any AWS KMS key that was used to encrypt the message. If you specify an AWS KMS key, it must be one of the wrapping keys used to encrypt the message.   
Specifying the wrapping key is an [AWS Encryption SDK best practice](best-practices.md). It assures that you use the AWS KMS key you intend to use.   
In a decrypt command, the value of the **key** attribute must be a [key ARN](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id-key-ARN).   

```
\\ AWS KMS key
aws-encryption-cli --decrypt --wrapping-keys key=arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
```

**Discovery: Use any AWS KMS key when decrypting**  <a name="discovery-cli-attribute"></a>
If you don't need to limit the AWS KMS keys to use when decrypting, you can use the **discovery** attribute with a value of `true`. A value of `true` allows the AWS Encryption CLI to decrypt using any AWS KMS key that encrypted the message. If you don't specify a **discovery** attribute, discovery is `false` (default). The **discovery** attribute is valid only in decrypt commands and only when the message was encrypted with AWS KMS keys.  
The **discovery** attribute with a value of `true` is an alternative to using the **key** attribute to specify AWS KMS keys. When decrypting a message encrypted with AWS KMS keys, each `--wrapping-keys` parameter must have a **key** attribute or a **discovery** attribute with a value of `true`, but not both.  
When discovery is true, it's a best practice to use the **discovery-partition** and **discovery-account** attributes to limit the AWS KMS keys used to those in the AWS accounts you specify. In the following example, the **discovery** attributes allow the AWS Encryption CLI to use any AWS KMS key in the specified AWS accounts.  

```
aws-encryption-cli --decrypt --wrapping-keys \
    discovery=true \
    discovery-partition=aws \
    discovery-account=111122223333 \
    discovery-account=444455556666
```

**Provider: Specify the master key provider**  
The **provider** attribute identifies the [master key provider](concepts.md#master-key-provider). The default value is `aws-kms`, which represents AWS KMS. If you are using a different master key provider, the **provider** attribute is required.  

```
--wrapping-keys key=12345 provider=my_custom_provider
```
For more information about using custom (non-AWS KMS) master key providers, see the **Advanced Configuration** topic in the [README](https://github.com/aws/aws-encryption-sdk-cli/blob/master/README.rst) file for the [AWS Encryption CLI](https://github.com/aws/aws-encryption-sdk-cli/) repository.

**Region: Specify an AWS Region**  
Use the **region** attribute to specify the AWS Region of an AWS KMS key. This attribute is valid only in encrypt commands and only when the master key provider is AWS KMS.   

```
--encrypt --wrapping-keys key=alias/primary-key region=us-east-2
```
AWS Encryption CLI commands use the AWS Region that is specified in the **key** attribute value if it includes a region, such as an ARN. if the **key** value specifies a AWS Region, the **region** attribute is ignored.  
The **region** attribute takes precedence over other region specifications. If you don't use a region attribute, AWS Encryption CLI commands uses the AWS Region specified in your AWS CLI [named profile](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html#cli-configure-files-using-profiles), if any, or your default profile.

**Profile: Specify a named profile**  
Use the **profile** attribute to specify an AWS CLI [named profile](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html#cli-configure-files-using-profiles). Named profiles can include credentials and an AWS Region. This attribute is valid only when the master key provider is AWS KMS.   

```
--wrapping-keys key=alias/primary-key profile=admin-1
```
You can use the **profile** attribute to specify alternate credentials in encrypt and decrypt commands. In an encrypt command, the AWS Encryption CLI uses the AWS Region in the named profile only when the **key** value does not include a region and there is no **region** attribute. In a decrypt command, the AWS Region in the name profile is ignored.

### How to specify multiple wrapping keys
<a name="cli-many-cmks"></a>

You can specify multiple wrapping keys (or *master keys*) in each command. 

If you specify more than one wrapping key, the first wrapping key generates and encrypts the data key that is used to encrypt your data. The other wrapping keys encrypt the same data key. The resulting [encrypted message](concepts.md#message) contains the encrypted data ("ciphertext") and a collection of encrypted data keys, one encrypted by each wrapping key. Any of the wrapping can decrypt one encrypted data key and then decrypt the data.

There are two ways to specify multiple wrapping keys: 
+ Include multiple **key** attributes in the `--wrapping-keys` parameter value.

  ```
  $key_oregon=arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
  $key_ohio=arn:aws:kms:us-east-2:111122223333:key/0987ab65-43cd-21ef-09ab-87654321cdef
  
  --wrapping-keys key=$key_oregon key=$key_ohio
  ```
+ Include multiple `--wrapping-keys` parameters in the same command. Use this syntax when the attribute values that you specify do not apply to all of the wrapping keys in the command.

  ```
  --wrapping-keys region=us-east-2 key=alias/test_key \
  --wrapping-keys region=us-west-1 key=alias/test_key
  ```

The **discovery** attribute with a value of `true` lets the AWS Encryption CLI use any AWS KMS key that encrypted the message. If you use multiple `--wrapping-keys` parameters in the same command, using `discovery=true` in any `--wrapping-keys` parameter effectively overrides the limits of the **key** attribute in other `--wrapping-keys` parameters. 

For example, in the following command, the **key** attribute in the first `--wrapping-keys` parameter limits the AWS Encryption CLI to the specified AWS KMS key. However, the **discovery** attribute in the second `--wrapping-keys` parameter lets the AWS Encryption CLI use any AWS KMS key in the specified accounts to decrypt the message.

```
aws-encryption-cli --decrypt \
    --wrapping-keys key=arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab \
    --wrapping-keys discovery=true \
                    discovery-partition=aws \
                    discovery-account=111122223333 \
                    discovery-account=444455556666
```

## How to provide input
<a name="crypto-cli-input"></a>

The encrypt operation in the AWS Encryption CLI takes plaintext data as input and returns an [encrypted message](concepts.md#message). The decrypt operation takes an encrypted message as input and returns plaintext data. 

The `--input` parameter (`-i`) , which tells the AWS Encryption CLI where to find the input, is required in all AWS Encryption CLI commands. 

You can provide input in any of the following ways:
+ Use a file.

  ```
  --input myData.txt
  ```
+ Use a file name pattern. 

  ```
  --input testdir/*.xml
  ```
+ Use a directory or directory name pattern. When the input is a directory, the `--recursive` parameter (`-r`, `-R`) is required.

  ```
  --input testdir --recursive
  ```
+ Pipe input to the command (stdin). Use a value of `-` for the `--input` parameter. (The `--input` parameter is always required.)

  ```
  echo 'Hello World' | aws-encryption-cli --encrypt --input -
  ```

## How to specify the output location
<a name="crypto-cli-output"></a>

The `--output` parameter tells the AWS Encryption CLI where to write the results of the encryption or decryption operation. It is required in every AWS Encryption CLI command. The AWS Encryption CLI creates a new output file for every input file in the operation. 

If an output file already exists, by default, the AWS Encryption CLI prints a warning, then overwrites the file. To prevent overwriting, use the `--interactive` parameter, which prompts you for confirmation before overwriting, or `--no-overwrite`, which skips the input if the output would cause an overwrite. To suppress the overwrite warning, use `--quiet`. To capture errors and warnings from the AWS Encryption CLI, use the `2>&1` redirection operator to write them to the output stream.

**Note**  
Commands that overwrite output files begin by deleting the output file. If the command fails, the output file might already be deleted.

You can the output location in several ways.
+ Specify a file name. If you specify a path to the file, all directories in the path must exist before the command runs. 

  ```
  --output myEncryptedData.txt
  ```
+ Specify a directory. The output directory must exist before the command runs. 

  If the input contains subdirectories, the command reproduces the subdirectories under the specified directory.

  ```
  --output Test
  ```

  When the output location is a directory (without file names), the AWS Encryption CLI creates output file names based on the input file names plus a suffix. Encrypt operations append `.encrypted` to the input file name and the decrypt operations append `.decrypted`. To change the suffix, use the `--suffix` parameter.

  For example, if you encrypt `file.txt`, the encrypt command creates `file.txt.encrypted`. If you decrypt `file.txt.encrypted`, the decrypt command creates `file.txt.encrypted.decrypted`.

   
+ Write to the command line (stdout). Enter a value of `-` for the `--output` parameter. You can use `--output -` to pipe output to another command or program.

  ```
  --output -
  ```

## How to use an encryption context
<a name="crypto-cli-encryption-context"></a>

The AWS Encryption CLI lets you provide an encryption context in encrypt and decrypt commands. It is not required, but it is a cryptographic best practice that we recommend.

An *encryption context* is a type of arbitrary, non-secret *additional authenticated data*. In the AWS Encryption CLI, the encryption context consists of a collection of `name=value` pairs. You can use any content in the pairs, including information about the files, data that helps you to find the encryption operation in logs, or data that your grants or policies require. 

**In an encrypt command**

The encryption context that you specify in an encrypt command, along with any additional pairs that the [CMM](concepts.md#crypt-materials-manager) adds, is cryptographically bound to the encrypted data. It is also included (in plaintext) in the [encrypted message](concepts.md#encryption-context) that the command returns. If you are using an AWS KMS key, the encryption context also might appear in plaintext in audit records and logs, such as AWS CloudTrail. 

The following example shows an encryption context with three `name=value` pairs.

```
--encryption-context purpose=test dept=IT class=confidential 
```

**In a decrypt command**

In a decrypt command, the encryption context helps you to confirm that you are decrypting the right encrypted message. 

You are not required to provide an encryption context in a decrypt command, even if an encryption context was used on encrypt. However, if you do, the AWS Encryption CLI verifies that every element in the encryption context of the decrypt command matches an element in the encryption context of the encrypted message. If any element does not match, the decrypt command fails. 

For example, the following command decrypts the encrypted message only if its encryption context includes `dept=IT`.

```
aws-encryption-cli --decrypt --encryption-context dept=IT ...
```

An encryption context is an important part of your security strategy. However, when choosing an encryption context, remember that its values are not secret. Do not include any confidential data in the encryption context.

**To specify an encryption context**
+ In an **encrypt** command, use the `--encryption-context` parameter with one or more `name=value` pairs. Use a space to separate each pair. 

  ```
  --encryption-context name=value [name=value] ...
  ```
+ In a **decrypt** command, the `--encryption-context` parameter value can include `name=value` pairs, `name` elements (with no values), or a combination of both.

  ```
  --encryption-context name[=value] [name] [name=value] ...
  ```

If the `name` or `value` in a `name=value` pair includes spaces or special characters, enclose the entire pair in quotation marks.

```
--encryption-context "department=software engineering" "AWS Region=us-west-2"
```

For example, this encrypt command includes an encryption context with two pairs, `purpose=test` and `dept=23`.

```
aws-encryption-cli --encrypt --encryption-context purpose=test dept=23 ...
```

These decrypt command would succeed. The encryption context in each commands is a subset of the original encryption context.

```
\\ Any one or both of the encryption context pairs
aws-encryption-cli --decrypt --encryption-context dept=23 ...

\\ Any one or both of the encryption context names
aws-encryption-cli --decrypt --encryption-context purpose ...

\\ Any combination of names and pairs
aws-encryption-cli --decrypt --encryption-context dept purpose=test ...
```

However, these decrypt commands would fail. The encryption context in the encrypted message does not contain the specified elements.

```
aws-encryption-cli --decrypt --encryption-context dept=Finance ...
aws-encryption-cli --decrypt --encryption-context scope ...
```

## How to specify a commitment policy
<a name="crypto-cli-commitment-policy"></a>

To set the [commitment policy](concepts.md#commitment-policy) for the command, use the [`--commitment-policy` parameter](crypto-cli-reference.md#syntax-commitment-policy). This parameter is introduced in version 1.8.*x*. It is valid in encrypt and decrypt commands. The commitment policy you set is valid only for the command in which it appears. If you do not set a commitment policy for a command, the AWS Encryption CLI uses the default value.

For example, the following parameter value sets the commitment policy to `require-encrypt-allow-decrypt`, which always encrypts with key commitment, but will decrypt a ciphertext that was encrypted with or without key commitment. 

```
--commitment-policy require-encrypt-allow-decrypt
```

## How to store parameters in a configuration file
<a name="crypto-cli-config-file"></a>

You can save time and avoid typing errors by saving frequently used AWS Encryption CLI parameters and values in configuration files. 

A *configuration file* is a text file that contains parameters and values for an AWS Encryption CLI command. When you refer to a configuration file in a AWS Encryption CLI command, the reference is replaced by the parameters and values in the configuration file. The effect is the same is if you typed the file content at the command line. A configuration file can have any name and it can be located in any directory that the current user can access. 

The following example configuration file, `key.conf`, specifies two AWS KMS keys in different Regions.

```
--wrapping-keys key=arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
--wrapping-keys key=arn:aws:kms:us-east-2:111122223333:key/0987ab65-43cd-21ef-09ab-87654321cdef
```

To use the configuration file in a command, prefix the file name with an at sign (`@`). In a PowerShell console, use a backtick character to escape the at sign (``@`).

This example command uses the `key.conf` file in an encrypt command.

------
#### [ Bash ]

```
$ aws-encryption-cli -e @key.conf -i hello.txt -o testdir  
```

------
#### [ PowerShell ]

```
PS C:\> aws-encryption-cli -e `@key.conf -i .\Hello.txt -o .\TestDir
```

------

**Configuration file rules**

The rules for using configuration files are as follows:
+ You can include multiple parameters in each configuration file and list them in any order. List each parameter with its values (if any) on a separate line. 
+ Use `#` to add a comment to all or part of a line.
+ You can include references to other configuration files. Do not use a backtick to escape the `@` sign, even in PowerShell.
+ If you use quotes in a configuration file, the quoted text cannot span multiple lines.

For example, this is the contents of an example `encrypt.conf` file.

```
# Archive Files
--encrypt
--output /archive/logs
--recursive
--interactive
--encryption-context class=unclassified dept=IT
--suffix  # No suffix
--metadata-output ~/metadata
@caching.conf  # Use limited caching
```

You can also include multiple configuration files in a command. This example command uses both the `encrypt.conf` and `master-keys.conf` configurations files.

------
#### [ Bash ]

```
$  aws-encryption-cli -i /usr/logs @encrypt.conf @master-keys.conf
```

------
#### [ PowerShell ]

```
PS C:\> aws-encryption-cli -i $home\Test\*.log `@encrypt.conf `@master-keys.conf
```

------

**Next: **[Try the AWS Encryption CLI examples](crypto-cli-examples.md)

# Examples of the AWS Encryption CLI
<a name="crypto-cli-examples"></a>

Use the following examples to try the AWS Encryption CLI on the platform you prefer. For help with master keys and other parameters, see [How to use the AWS Encryption CLI](crypto-cli-how-to.md). For a quick reference, see [AWS Encryption SDK CLI syntax and parameter reference](crypto-cli-reference.md).

**Note**  
The following examples use the syntax for AWS Encryption CLI version 2.1.*x*.   
New security features were originally released in AWS Encryption CLI versions 1.7.*x* and 2.0.*x*. However, AWS Encryption CLI version 1.8.*x* replaces version 1.7.*x* and AWS Encryption CLI 2.1.*x* replaces 2.0.*x*. For details, see the relevant [security advisory](https://github.com/aws/aws-encryption-sdk-cli/security/advisories/GHSA-2xwp-m7mq-7q3r) in the [aws-encryption-sdk-cli](https://github.com/aws/aws-encryption-sdk-cli/) repository on GitHub.

For an example showing how to use the security feature that limits encrypted data keys, see [Limiting encrypted data keys](configure.md#config-limit-keys).

For an example showing how to use AWS KMS multi-Region keys, see [Using multi-Region AWS KMS keys](configure.md#config-mrks).

**Topics**
+ [

## Encrypting a file
](#cli-example-encrypt-file)
+ [

## Decrypting a file
](#cli-example-decrypt-file)
+ [

## Encrypting all files in a directory
](#cli-example-encrypt-directory)
+ [

## Decrypting all files in a directory
](#cli-example-decrypt-directory)
+ [

## Encrypting and decrypting on the command line
](#cli-example-stdin)
+ [

## Using multiple master keys
](#cli-example-multimaster)
+ [

## Encrypting and decrypting in scripts
](#cli-example-script)
+ [

## Using data key caching
](#cli-example-caching)

## Encrypting a file
<a name="cli-example-encrypt-file"></a>

This example uses the AWS Encryption CLI to encrypt the contents of the `hello.txt` file, which contains a "Hello World" string. 

When you run an encrypt command on a file, the AWS Encryption CLI gets the contents of the file, generates a unique [data key](concepts.md#DEK), encrypts the file contents under the data key, and then writes the [encrypted message](concepts.md#message) to a new file. 

The first command saves the key ARN of an AWS KMS key in the `$keyArn` variable. When encrypting with an AWS KMS key, you can identify it by using a key ID, key ARN, alias name, or alias ARN. For details about the key identifiers for an AWS KMS key, see [Key Identifiers](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id) in the *AWS Key Management Service Developer Guide*.

The second command encrypts the file contents. The command uses the `--encrypt` parameter to specify the operation and the `--input` parameter to indicate the file to encrypt. The [`--wrapping-keys` parameter](crypto-cli-how-to.md#crypto-cli-master-key), and its required **key** attribute, tell the command to use the AWS KMS key represented by the key ARN. 

The command uses the `--metadata-output` parameter to specify a text file for the metadata about the encryption operation. As a best practice, the command uses the `--encryption-context` parameter to specify an [encryption context](crypto-cli-how-to.md#crypto-cli-encryption-context). 

This command also uses the [`--commitment-policy` parameter](crypto-cli-reference.md#syntax-commitment-policy) to set the commitment policy explicitly. In version 1.8.*x*, this parameter is required when you use the `--wrapping-keys` parameter. Beginning in version 2.1.*x*, the `--commitment-policy` parameter is optional, but recommended.

The value of the `--output` parameter, a dot (.), tells the command to write the output file to the current directory. 

------
#### [ Bash ]

```
\\ To run this example, replace the fictitious key ARN with a valid value.
$ keyArn=arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab

$ aws-encryption-cli --encrypt \
                     --input hello.txt \
                     --wrapping-keys key=$keyArn \
                     --metadata-output ~/metadata \
                     --encryption-context purpose=test \
                     --commitment-policy require-encrypt-require-decrypt \
                     --output .
```

------
#### [ PowerShell ]

```
# To run this example, replace the fictitious key ARN with a valid value.
PS C:\> $keyArn = 'arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab'

PS C:\> aws-encryption-cli --encrypt `
                           --input Hello.txt `
                           --wrapping-keys key=$keyArn `
                           --metadata-output $home\Metadata.txt `
                           --commitment-policy require-encrypt-require-decrypt `
                           --encryption-context purpose=test `
                           --output .
```

------

When the encrypt command succeeds, it does not return any output. To determine whether the command succeeded, check the Boolean value in the `$?` variable. When the command succeeds, the value of `$?` is `0` (Bash) or `True` (PowerShell). When the command fails, the value of `$?` is non-zero (Bash) or `False` (PowerShell).

------
#### [ Bash ]

```
$ echo $?
0
```

------
#### [ PowerShell ]

```
PS C:\> $?
True
```

------

You can also use a directory listing command to see that the encrypt command created a new file, `hello.txt.encrypted`. Because the encrypt command did not specify a file name for the output, the AWS Encryption CLI wrote the output to a file with the same name as the input file plus a `.encrypted` suffix. To use a different suffix, or suppress the suffix, use the `--suffix` parameter.

The `hello.txt.encrypted` file contains an [encrypted message](concepts.md#message) that includes the ciphertext of the `hello.txt` file, an encrypted copy of the data key, and additional metadata, including the encryption context.

------
#### [ Bash ]

```
$  ls
hello.txt  hello.txt.encrypted
```

------
#### [ PowerShell ]

```
PS C:\> dir

    Directory: C:\TestCLI

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----        9/15/2017   5:57 PM             11 Hello.txt
-a----        9/17/2017   1:06 PM            585 Hello.txt.encrypted
```

------

## Decrypting a file
<a name="cli-example-decrypt-file"></a>

This example uses the AWS Encryption CLI to decrypt the contents of the `Hello.txt.encrypted` file that was encrypted in the previous example.

The decrypt command uses the `--decrypt` parameter to indicate the operation and `--input` parameter to identify the file to decrypt. The value of the `--output` parameter is a dot that represents the current directory. 

The `--wrapping-keys` parameter with a **key** attribute specifies the wrapping key used to decrypt the encrypted message. In decrypt commands with AWS KMS keys, the value of the key attribute must be a [key ARN](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id-key-ARN). The `--wrapping-keys` parameter is required in a decrypt command. If you are using AWS KMS keys, you can use the **key** attribute to specify AWS KMS keys for decrypting or the **discovery** attribute with a value of `true` (but not both). If you are using a custom master key provider, the **key** and **provider** attributes are required. 

The [`--commitment-policy` parameter](crypto-cli-reference.md#syntax-commitment-policy) is optional beginning in version 2.1.*x*, but it is recommended. Using it explicitly makes your intent clear, even if you specify the default value, `require-encrypt-require-decrypt`.

The `--encryption-context` parameter is optional in the decrypt command, even when an [encryption context](crypto-cli-how-to.md#crypto-cli-encryption-context) is provided in the encrypt command. In this case, the decrypt command uses the same encryption context that was provided in the encrypt command. Before decrypting, the AWS Encryption CLI verifies that the encryption context in the encrypted message includes a `purpose=test` pair. If it does not, the decrypt command fails.

The `--metadata-output` parameter specifies a file for metadata about the decryption operation. The value of the `--output` parameter, a dot (.), writes the output file to the current directory. 

As a best practice, use the `--max-encrypted-data-keys` parameter to avoid decrypting a malformed message with an excessive number of encrypted data keys. Specify the expected number of encrypted data keys (one for each wrapping key used in encryption) or a reasonable maximum (such as 5). For details, see [Limiting encrypted data keys](configure.md#config-limit-keys).

The `--buffer` returns plaintext only after all input is processed, including verifying the digital signature if one is present.

------
#### [ Bash ]

```
\\ To run this example, replace the fictitious key ARN with a valid value.
$ keyArn=arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab

$ aws-encryption-cli --decrypt \
                     --input hello.txt.encrypted \
                     --wrapping-keys key=$keyArn \
                     --commitment-policy require-encrypt-require-decrypt \
                     --encryption-context purpose=test \
                     --metadata-output ~/metadata \
                     --max-encrypted-data-keys 1 \
                     --buffer \
                     --output .
```

------
#### [ PowerShell ]

```
\\ To run this example, replace the fictitious key ARN with a valid value.
PS C:\> $keyArn = 'arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab'

PS C:\> aws-encryption-cli --decrypt `
                           --input Hello.txt.encrypted `
                           --wrapping-keys key=$keyArn `
                           --commitment-policy require-encrypt-require-decrypt `
                           --encryption-context purpose=test `
                           --metadata-output $home\Metadata.txt `
                           --max-encrypted-data-keys 1 `
                           --buffer `
                           --output .
```

------

When a decrypt command succeeds, it does not return any output. To determine whether the command succeeded, get the value of the `$?` variable. You can also use a directory listing command to see that the command created a new file with a `.decrypted` suffix. To see the plaintext content, use a command to get the file content, such as `cat` or [Get-Content](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/get-content).

------
#### [ Bash ]

```
$  ls
hello.txt  hello.txt.encrypted  hello.txt.encrypted.decrypted

$  cat hello.txt.encrypted.decrypted
Hello World
```

------
#### [ PowerShell ]

```
PS C:\> dir

    Directory: C:\TestCLI

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----        9/17/2017   1:01 PM             11 Hello.txt
-a----        9/17/2017   1:06 PM            585 Hello.txt.encrypted
-a----        9/17/2017   1:08 PM             11 Hello.txt.encrypted.decrypted


PS C:\> Get-Content Hello.txt.encrypted.decrypted
Hello World
```

------

## Encrypting all files in a directory
<a name="cli-example-encrypt-directory"></a>

This example uses the AWS Encryption CLI to encrypt the contents of all of the files in a directory. 

When a command affects multiple files, the AWS Encryption CLI processes each file individually. It gets the file contents, gets a unique [data key](concepts.md#DEK) for the file from the master key, encrypts the file contents under the data key, and writes the results to a new file in the output directory. As a result, you can decrypt the output files independently. 

This listing of the `TestDir` directory shows the plaintext files that we want to encrypt. 

------
#### [ Bash ]

```
$  ls testdir
cool-new-thing.py  hello.txt  employees.csv
```

------
#### [ PowerShell ]

```
PS C:\> dir C:\TestDir

    Directory: C:\TestDir

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----        9/12/2017   3:11 PM           2139 cool-new-thing.py
-a----        9/15/2017   5:57 PM             11 Hello.txt
-a----        9/17/2017   1:44 PM             46 Employees.csv
```

------

The first command saves the [Amazon Resource Name (ARN)](https://docs.aws.amazon.com/kms/latest/developerguide/viewing-keys.html#find-cmk-id-arn) of an AWS KMS key in the `$keyArn` variable.

The second command encrypts the content of files in the `TestDir` directory and writes the files of encrypted content to the `TestEnc` directory. If the `TestEnc` directory doesn't exist, the command fails. Because the input location is a directory, the `--recursive` parameter is required. 

The [`--wrapping-keys` parameter](crypto-cli-how-to.md#crypto-cli-master-key), and its required **key** attribute, specify the wrapping key to use. The encrypt command includes an [encryption context](crypto-cli-how-to.md#crypto-cli-encryption-context), `dept=IT`. When you specify an encryption context in a command that encrypts multiple files, the same encryption context is used for all of the files. 

The command also has a `--metadata-output` parameter to tell the AWS Encryption CLI where to write the metadata about the encryption operations. The AWS Encryption CLI writes one metadata record for each file that was encrypted.

The [`--commitment-policy parameter`](crypto-cli-how-to.md#crypto-cli-commitment-policy) is optional beginning in version 2.1.*x*, but it is recommended. If the command or script fails because it cannot decrypt a ciphertext, the explicit commitment policy setting might help you to detect the problem quickly.

When the command completes, the AWS Encryption CLI writes the encrypted files to the `TestEnc` directory, but it does not return any output. 

The final command lists the files in the `TestEnc` directory. There is one output file of encrypted content for each input file of plaintext content. Because the command did not specify an alternate suffix, the encrypt command appended `.encrypted` to each of the input file names.

------
#### [ Bash ]

```
# To run this example, replace the fictitious key ARN with a valid master key identifier.
$  keyArn=arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab

$ aws-encryption-cli --encrypt \
                     --input testdir --recursive\
                     --wrapping-keys key=$keyArn \
                     --encryption-context dept=IT \
                     --commitment-policy require-encrypt-require-decrypt \
                     --metadata-output ~/metadata \
                     --output testenc

$ ls testenc
cool-new-thing.py.encrypted  employees.csv.encrypted  hello.txt.encrypted
```

------
#### [ PowerShell ]

```
# To run this example, replace the fictitious key ARN with a valid master key identifier.
PS C:\> $keyArn = arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab

PS C:\> aws-encryption-cli --encrypt `
                           --input .\TestDir --recursive `
                           --wrapping-keys key=$keyArn `
                           --encryption-context dept=IT `
                           --commitment-policy require-encrypt-require-decrypt `
                           --metadata-output .\Metadata\Metadata.txt `
                           --output .\TestEnc

PS C:\> dir .\TestEnc

    Directory: C:\TestEnc

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----        9/17/2017   2:32 PM           2713 cool-new-thing.py.encrypted
-a----        9/17/2017   2:32 PM            620 Hello.txt.encrypted
-a----        9/17/2017   2:32 PM            585 Employees.csv.encrypted
```

------

## Decrypting all files in a directory
<a name="cli-example-decrypt-directory"></a>

This example decrypts all files in a directory. It starts with the files in the `TestEnc` directory that were encrypted in the previous example.

------
#### [ Bash ]

```
$  ls testenc
cool-new-thing.py.encrypted  hello.txt.encrypted  employees.csv.encrypted
```

------
#### [ PowerShell ]

```
PS C:\> dir C:\TestEnc

    Directory: C:\TestEnc

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----        9/17/2017   2:32 PM           2713 cool-new-thing.py.encrypted
-a----        9/17/2017   2:32 PM            620 Hello.txt.encrypted
-a----        9/17/2017   2:32 PM            585 Employees.csv.encrypted
```

------

This decrypt command decrypts all of the files in the TestEnc directory and writes the plaintext files to the TestDec directory. The `--wrapping-keys` parameter with a **key** attribute and a [key ARN](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id-key-ARN) value tells the AWS Encryption CLI which AWS KMS keys to use to decrypt the files. The command uses the `--interactive` parameter to tell the AWS Encryption CLI to prompt you before overwriting a file with the same name.

This command also uses the encryption context that was provided when the files were encrypted. When decrypting multiple files, the AWS Encryption CLI checks the encryption context of every file. If the encryption context check on any file fails, the AWS Encryption CLI rejects the file, writes a warning, records the failure in the metadata, and then continues checking the remaining files. If the AWS Encryption CLI fails to decrypt a file for any other reason, the entire decrypt command fails immediately. 

In this example, the encrypted messages in all of the input files contain the `dept=IT` encryption context element. However, if you were decrypting messages with different encryption contexts, you might still be able to verify part of the encryption context. For example, if some messages had an encryption context of `dept=finance` and others had `dept=IT`, you could verify that the encryption context always contains a `dept` name without specifying the value. If you wanted to be more specific, you could decrypt the files in separate commands. 

The decrypt command does not return any output, but you can use a directory listing command to see that it created new files with the `.decrypted` suffix. To see the plaintext content, use a command to get the file content.

------
#### [ Bash ]

```
# To run this example, replace the fictitious key ARN with a valid master key identifier.
$ keyArn=arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab

$ aws-encryption-cli --decrypt \
                     --input testenc --recursive \
                     --wrapping-keys key=$keyArn \
                     --encryption-context dept=IT \
                     --commitment-policy require-encrypt-require-decrypt \
                     --metadata-output ~/metadata \
                     --max-encrypted-data-keys 1 \
                     --buffer \
                     --output testdec --interactive

$ ls testdec
cool-new-thing.py.encrypted.decrypted  hello.txt.encrypted.decrypted  employees.csv.encrypted.decrypted
```

------
#### [ PowerShell ]

```
# To run this example, replace the fictitious key ARN with a valid master key identifier.
PS C:\> $keyArn = 'arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab'

PS C:\> aws-encryption-cli --decrypt `
                           --input C:\TestEnc --recursive `
                           --wrapping-keys key=$keyArn `
                           --encryption-context dept=IT `
                           --commitment-policy require-encrypt-require-decrypt `
                           --metadata-output $home\Metadata.txt `
                           --max-encrypted-data-keys 1 `
                           --buffer `
                           --output C:\TestDec --interactive

PS C:\> dir .\TestDec


    Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----        10/8/2017   4:57 PM           2139 cool-new-thing.py.encrypted.decrypted
-a----        10/8/2017   4:57 PM             46 Employees.csv.encrypted.decrypted
-a----        10/8/2017   4:57 PM             11 Hello.txt.encrypted.decrypted
```

------

## Encrypting and decrypting on the command line
<a name="cli-example-stdin"></a>

These examples show you how to pipe input to commands (stdin) and write output to the command line (stdout). They explain how to represent stdin and stdout in a command and how to use the built-in Base64 encoding tools to prevent the shell from misinterpreting non-ASCII characters.

This example pipes a plaintext string to an encrypt command and saves the encrypted message in a variable. Then, it pipes the encrypted message in the variable to a decrypt command, which writes its output to the pipeline (stdout). 

The example consists of three commands:
+ The first command saves the [key ARN](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id-key-ARN) of an AWS KMS key in the `$keyArn` variable.

------
#### [ Bash ]

  ```
  $  keyArn=arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
  ```

------
#### [ PowerShell ]

  ```
  PS C:\> $keyArn = 'arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab'
  ```

------

   
+ The second command pipes the `Hello World` string to the encrypt command and saves the result in the `$encrypted` variable. 

  The `--input` and `--output` parameters are required in all AWS Encryption CLI commands. To indicate that input is being piped to the command (stdin), use a hyphen (`-`) for the value of the `--input` parameter. To send the output to the command line (stdout), use a hyphen for the value of the `--output` parameter. 

  The `--encode` parameter Base64-encodes the output before returning it. This prevents the shell from misinterpreting the non-ASCII characters in the encrypted message. 

  Because this command is just a proof of concept, we omit the encryption context and suppress the metadata (`-S`). 

------
#### [ Bash ]

  ```
  $ encrypted=$(echo 'Hello World' | aws-encryption-cli --encrypt -S \
                                                        --input - --output - --encode \
                                                        --wrapping-keys key=$keyArn )
  ```

------
#### [ PowerShell ]

  ```
  PS C:\> $encrypted = 'Hello World' | aws-encryption-cli --encrypt -S `
                                                          --input - --output - --encode `
                                                          --wrapping-keys key=$keyArn
  ```

------

   
+ The third command pipes the encrypted message in the `$encrypted` variable to the decrypt command. 

  This decrypt command uses `--input -` to indicate that input is coming from the pipeline (stdin) and `--output -` to send the output to the pipeline (stdout). (The input parameter takes the location of the input, not the actual input bytes, so you cannot use the `$encrypted` variable as the value of the `--input` parameter.) 

  This example uses the **discovery** attribute of the `--wrapping-keys` parameter to allow the AWS Encryption CLI to use any AWS KMS key to decrypt the data. It doesn't specify a [commitment policy](concepts.md#commitment-policy), so it uses the default value for version 2.1.*x* and later, `require-encrypt-require-decrypt`.

  Because the output was encrypted and then encoded, the decrypt command uses the `--decode` parameter to decode Base64-encoded input before decrypting it. You can also use the `--decode` parameter to decode Base64-encoded input before encrypting it.

  Again, the command omits the encryption context and suppresses the metadata (-`S`). 

------
#### [ Bash ]

  ```
  $  echo $encrypted | aws-encryption-cli --decrypt --wrapping-keys discovery=true --input - --output - --decode --buffer -S
  Hello World
  ```

------
#### [ PowerShell ]

  ```
  PS C:\> $encrypted | aws-encryption-cli --decrypt --wrapping-keys discovery=$true --input - --output - --decode --buffer -S
  Hello World
  ```

------

You can also perform the encrypt and decrypt operations in a single command without the intervening variable. 

As in the previous example, the `--input` and `--output` parameters have a `-` value and the command uses the `--encode` parameter to encode the output and the `--decode` parameter to decode the input.

------
#### [ Bash ]

```
$  keyArn=arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab

$  echo 'Hello World' |
          aws-encryption-cli --encrypt --wrapping-keys key=$keyArn --input - --output - --encode -S |
          aws-encryption-cli --decrypt --wrapping-keys discovery=true --input - --output - --decode -S
Hello World
```

------
#### [ PowerShell ]

```
PS C:\> $keyArn = 'arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab'

PS C:\> 'Hello World' |
               aws-encryption-cli --encrypt --wrapping-keys key=$keyArn --input - --output - --encode -S |
               aws-encryption-cli --decrypt --wrapping-keys discovery=$true --input - --output - --decode -S
Hello World
```

------

## Using multiple master keys
<a name="cli-example-multimaster"></a>

This example shows how to use multiple master keys when encrypting and decrypting data in the AWS Encryption CLI. 

When you use multiple master keys to encrypt data, any one of the master keys can be used to decrypt the data. This strategy assures that you can decrypt the data even if one of the master keys is unavailable. If you are storing the encrypted data in multiple AWS Regions, this strategy lets you use a master key in the same Region to decrypt the data. 

When you encrypt with multiple master keys, the first master key plays a special role. It generates the data key that is used to encrypt the data. The remaining master keys encrypt the plaintext data key. The resulting [encrypted message](concepts.md#message) includes the encrypted data and a collection of encrypted data keys, one for each master key. Although the first master key generated the data key, any of the master keys can decrypt one of the data keys, which can be used to decrypt the data. 

**Encrypting with three master keys**

This example command uses three wrapping keys to encrypt the `Finance.log` file, one in each of three AWS Regions. 

It writes the encrypted message to the `Archive` directory. The command uses the `--suffix` parameter with no value to suppress the suffix, so the input and output files names will be the same. 

The command uses the `--wrapping-keys` parameter with three **key** attributes. You can also use multiple `--wrapping-keys` parameters in the same command. 

To encrypt the log file, the AWS Encryption CLI asks the first wrapping key in the list, `$key1`, to generate the data key that it uses to encrypt the data. Then, it uses each of the other wrapping keys to encrypt a plaintext copy of the same data key. The encrypted message in the output file includes all three of the encrypted data keys. 

------
#### [ Bash ]

```
$ key1=arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
$ key2=arn:aws:kms:us-east-2:111122223333:key/0987ab65-43cd-21ef-09ab-87654321cdef
$ key3=arn:aws:kms:ap-southeast-1:111122223333:key/1a2b3c4d-5e6f-1a2b-3c4d-5e6f1a2b3c4d

$ aws-encryption-cli --encrypt --input /logs/finance.log \
                               --output /archive --suffix \
                               --encryption-context class=log \
                               --metadata-output ~/metadata \
                               --wrapping-keys key=$key1 key=$key2 key=$key3
```

------
#### [ PowerShell ]

```
PS C:\> $key1 = 'arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab'
PS C:\> $key2 = 'arn:aws:kms:us-east-2:111122223333:key/0987ab65-43cd-21ef-09ab-87654321cdef'
PS C:\> $key3 = 'arn:aws:kms:ap-southeast-1:111122223333:key/1a2b3c4d-5e6f-1a2b-3c4d-5e6f1a2b3c4d'

PS C:\> aws-encryption-cli --encrypt --input D:\Logs\Finance.log `
                           --output D:\Archive --suffix `
                           --encryption-context class=log `
                           --metadata-output $home\Metadata.txt `
                           --wrapping-keys key=$key1 key=$key2 key=$key3
```

------

This command decrypts the encrypted copy of the `Finance.log` file and writes it to a `Finance.log.clear` file in the `Finance` directory. To decrypt data encrypted under three AWS KMS keys, you can specify the same three AWS KMS keys or any subset of them. This example specifies only one of the AWS KMS keys.

To tell the AWS Encryption CLI which AWS KMS keys to use to decrypt your data, use the **key** attribute of the `--wrapping-keys` parameter. When decrypting with AWS KMS keys, the value of the **key** attribute must be a [key ARN](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id-key-ARN).

You must have permission to call the [Decrypt API](https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.html) on the AWS KMS keys you specify. For more information, see [ Authentication and Access Control for AWS KMS](https://docs.aws.amazon.com/kms/latest/developerguide/control-access.html). 

As a best practice, this examples use the `--max-encrypted-data-keys` parameter to avoid decrypting a malformed message with an excessive number of encrypted data keys. Even though this example uses only one wrapping key for decryption, the encrypted message has three (3) encrypted data keys; one for each of the three wrapping keys used when encrypting. Specify the expected number of encrypted data keys or a reasonable maximum value, such as 5. If you specify a maximum value less than 3, the command fails. For details, see [Limiting encrypted data keys](configure.md#config-limit-keys).

------
#### [ Bash ]

```
$ aws-encryption-cli --decrypt --input /archive/finance.log \
                     --wrapping-keys key=$key1 \
                     --output /finance --suffix '.clear' \
                     --metadata-output ~/metadata \
                     --max-encrypted-data-keys 3 \
                     --buffer \
                     --encryption-context class=log
```

------
#### [ PowerShell ]

```
PS C:\> aws-encryption-cli --decrypt `
                           --input D:\Archive\Finance.log `
                           --wrapping-keys key=$key1 `
                           --output D:\Finance --suffix '.clear' `
                           --metadata-output .\Metadata\Metadata.txt `
                           --max-encrypted-data-keys 3 `
                           --buffer `
                           --encryption-context class=log
```

------

## Encrypting and decrypting in scripts
<a name="cli-example-script"></a>

This example shows how to use the AWS Encryption CLI in scripts. You can write scripts that just encrypt and decrypt data, or scripts that encrypt or decrypt as part of a data management process.

In this example, the script gets a collection of log files, compresses them, encrypts them, and then copies the encrypted files to an Amazon S3 bucket. This script processes each file separately, so that you can decrypt and expand them independently.

When you compress and encrypt files, be sure to compress before you encrypt. Properly encrypted data is not compressible.

**Warning**  
Be careful when compressing data that includes both secrets and data that might be controlled by a malicious actor. The final size of the compressed data might inadvertently reveal sensitive information about its contents.

------
#### [ Bash ]

```
# Continue running even if an operation fails.
set +e

dir=$1
encryptionContext=$2
s3bucket=$3
s3folder=$4
masterKeyProvider="aws-kms"
metadataOutput="/tmp/metadata-$(date +%s)"

compress(){
    gzip -qf $1
}

encrypt(){
    # -e encrypt
    # -i input
    # -o output
    # --metadata-output unique file for metadata
    # -m masterKey read from environment variable
    # -c encryption context read from the second argument.
    # -v be verbose
    aws-encryption-cli -e -i ${1} -o $(dirname ${1}) --metadata-output ${metadataOutput} -m key="${masterKey}" provider="${masterKeyProvider}" -c "${encryptionContext}" -v
}


s3put (){
    # copy file argument 1 to s3 location passed into the script.
    aws s3 cp ${1} ${s3bucket}/${s3folder}
}

# Validate all required arguments are present.
if [ "${dir}" ] && [ "${encryptionContext}" ] && [ "${s3bucket}" ] && [ "${s3folder}" ] && [ "${masterKey}" ]; then

# Is $dir a valid directory?
test -d "${dir}"
if [ $? -ne 0 ]; then
    echo "Input is not a directory; exiting"
    exit 1
fi

# Iterate over all the files in the directory, except *gz and *encrypted (in case of a re-run).
for f in $(find ${dir} -type f \( -name "*" ! -name \*.gz ! -name \*encrypted \) ); do
    echo "Working on $f"
    compress ${f}
    encrypt ${f}.gz
    rm -f ${f}.gz
    s3put ${f}.gz.encrypted
done;
else
    echo "Arguments: <Directory> <encryption context> <s3://bucketname> <s3 folder>"
    echo " and ENV var \$masterKey must be set"
    exit 255
fi
```

------
#### [ PowerShell ]

```
#Requires -Modules AWSPowerShell, Microsoft.PowerShell.Archive
Param
(
    [Parameter(Mandatory)]
    [ValidateScript({Test-Path $_})]
    [String[]]
    $FilePath,

    [Parameter()]
    [Switch]
    $Recurse,

    [Parameter(Mandatory=$true)]
    [String]
    $wrappingKeyID,

    [Parameter()]
    [String]
    $masterKeyProvider = 'aws-kms',

    [Parameter(Mandatory)]
    [ValidateScript({Test-Path $_})]
    [String]
    $ZipDirectory,

    [Parameter(Mandatory)]
    [ValidateScript({Test-Path $_})]
    [String]
    $EncryptDirectory,

    [Parameter()]
    [String]
    $EncryptionContext,

    [Parameter(Mandatory)]
    [ValidateScript({Test-Path $_})]
    [String]
    $MetadataDirectory,

    [Parameter(Mandatory)]
    [ValidateScript({Test-S3Bucket -BucketName $_})]
    [String]
    $S3Bucket,

    [Parameter()]
    [String]
    $S3BucketFolder
)

BEGIN {}
PROCESS {
    if ($files = dir $FilePath -Recurse:$Recurse)
    {

        # Step 1: Compress
        foreach ($file in $files)
        {
            $fileName = $file.Name
            try
            {
                Microsoft.PowerShell.Archive\Compress-Archive -Path $file.FullName -DestinationPath $ZipDirectory\$filename.zip
            }
            catch
            {
                Write-Error "Zip failed on $file.FullName"
            }

            # Step 2: Encrypt
            if (-not (Test-Path "$ZipDirectory\$filename.zip"))
            {
                Write-Error "Cannot find zipped file: $ZipDirectory\$filename.zip"
            }
            else
            {
                # 2>&1 captures command output
                $err = (aws-encryption-cli -e -i "$ZipDirectory\$filename.zip" `
                                           -o $EncryptDirectory `
                                           -m key=$wrappingKeyID provider=$masterKeyProvider `
                                           -c $EncryptionContext `
                                           --metadata-output $MetadataDirectory `
                                           -v) 2>&1

                # Check error status
                if ($? -eq $false)
                {
                    # Write the error
                    $err
                }
                elseif (Test-Path "$EncryptDirectory\$fileName.zip.encrypted")
                {
                    # Step 3: Write to S3 bucket
                    if ($S3BucketFolder)
                    {
                        Write-S3Object -BucketName $S3Bucket -File "$EncryptDirectory\$fileName.zip.encrypted" -Key "$S3BucketFolder/$fileName.zip.encrypted"

                    }
                    else
                    {
                        Write-S3Object -BucketName $S3Bucket -File "$EncryptDirectory\$fileName.zip.encrypted"
                    }
                }
            }
        }
    }
}
```

------

## Using data key caching
<a name="cli-example-caching"></a>

This example uses [data key caching](data-key-caching.md) in a command that encrypts a large number of files. 

By default, the AWS Encryption CLI (and other versions of the AWS Encryption SDK) generates a unique data key for each file that it encrypts. Although using a unique data key for each operation is a cryptographic best practice, limited reuse of data keys is acceptable for some situations. If you are considering data key caching, consult with a security engineer to understand the security requirements of your application and determine security thresholds that are right for you. 

In this example, data key caching speeds up the encryption operation by reducing the frequency of requests to the master key provider.

The command in this example encrypts a large directory with multiple subdirectories that contain a total of approximately 800 small log files. The first command saves the ARN of the AWS KMS key in a `keyARN` variable. The second command encrypts all of the files in the input directory (recursively) and writes them to an archive directory. The command uses the `--suffix` parameter to specify the `.archive` suffix. 

The `--caching` parameter enables data key caching. The **capacity** attribute, which limits the number of data keys in the cache, is set to 1, because serial file processing never uses more than one data key at a time. The **max\$1age** attribute, which determines how long the cached data key can used, is set to 10 seconds. 

The optional **max\$1messages\$1encrypted** attribute is set to 10 messages, so a single data key is never used to encrypt more than 10 files. Limiting the number of files encrypted by each data key reduces the number of files that would be affected in the unlikely event that a data key was compromised.

To run this command on log files that your operating system generates, you might need administrator permissions (`sudo` in Linux; **Run as Administrator** in Windows).

------
#### [ Bash ]

```
$  keyArn=arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab

$  aws-encryption-cli --encrypt \
                      --input /var/log/httpd --recursive \
                      --output ~/archive --suffix .archive \
                      --wrapping-keys key=$keyArn \
                      --encryption-context class=log \
                      --suppress-metadata \
                      --caching capacity=1 max_age=10 max_messages_encrypted=10
```

------
#### [ PowerShell ]

```
PS C:\> $keyARN = 'arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab'

PS C:\> aws-encryption-cli --encrypt `
                           --input C:\Windows\Logs --recursive `
                           --output $home\Archive --suffix '.archive' `
                           --wrapping-keys key=$keyARN `
                           --encryption-context class=log `
                           --suppress-metadata `
                           --caching capacity=1 max_age=10 max_messages_encrypted=10
```

------

To test the effect of data key caching, this example uses the [Measure-Command](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/measure-command) cmdlet in PowerShell. When you run this example without data key caching, it takes about 25 seconds to complete. This process generates a new data key for each file in the directory.

```
PS C:\> Measure-Command {aws-encryption-cli --encrypt `
                                            --input C:\Windows\Logs --recursive `
                                            --output $home\Archive  --suffix '.archive' `
                                            --wrapping-keys key=$keyARN `
                                            --encryption-context class=log `
                                            --suppress-metadata }


Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 25
Milliseconds      : 453
Ticks             : 254531202
TotalDays         : 0.000294596298611111
TotalHours        : 0.00707031116666667
TotalMinutes      : 0.42421867
TotalSeconds      : 25.4531202
TotalMilliseconds : 25453.1202
```

Data key caching makes the process quicker, even when you limit each data key to a maximum of 10 files. The command now takes less than 12 seconds to complete and reduces the number of calls to the master key provider to 1/10 of the original value.

```
PS C:\> Measure-Command {aws-encryption-cli --encrypt `
                                            --input C:\Windows\Logs --recursive `
                                            --output $home\Archive  --suffix '.archive' `
                                            --wrapping-keys key=$keyARN `
                                            --encryption-context class=log `
                                            --suppress-metadata `
                                            --caching capacity=1 max_age=10 max_messages_encrypted=10}


Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 11
Milliseconds      : 813
Ticks             : 118132640
TotalDays         : 0.000136727592592593
TotalHours        : 0.00328146222222222
TotalMinutes      : 0.196887733333333
TotalSeconds      : 11.813264
TotalMilliseconds : 11813.264
```

If you eliminate the `max_messages_encrypted` restriction, all files are encrypted under the same data key. This change increases the risk of reusing data keys without making the process much faster. However, it reduces the number of calls to the master key provider to 1.

```
PS C:\> Measure-Command {aws-encryption-cli --encrypt `
                                            --input C:\Windows\Logs --recursive `
                                            --output $home\Archive  --suffix '.archive' `
                                            --wrapping-keys key=$keyARN `
                                            --encryption-context class=log `
                                            --suppress-metadata `
                                            --caching capacity=1 max_age=10}


Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 10
Milliseconds      : 252
Ticks             : 102523367
TotalDays         : 0.000118661304398148
TotalHours        : 0.00284787130555556
TotalMinutes      : 0.170872278333333
TotalSeconds      : 10.2523367
TotalMilliseconds : 10252.3367
```

# AWS Encryption SDK CLI syntax and parameter reference
<a name="crypto-cli-reference"></a>

This topic provides syntax diagrams and brief parameter descriptions to help you use the AWS Encryption SDK Command Line Interface (CLI). For help with wrapping keys and other parameters, see [How to use the AWS Encryption CLI](crypto-cli-how-to.md). For examples, see [Examples of the AWS Encryption CLI](crypto-cli-examples.md). For complete documentation, see [Read the Docs](https://aws-encryption-sdk-cli.readthedocs.io/en/latest/).

**Topics**
+ [

## AWS Encryption CLI syntax
](#crypto-cli-syntax)
+ [

## AWS Encryption CLI command line parameters
](#crypto-cli-parameters)
+ [

## Advanced parameters
](#cli-advanced-parameters)

## AWS Encryption CLI syntax
<a name="crypto-cli-syntax"></a>

These AWS Encryption CLI syntax diagrams show the syntax for each task that you perform with the AWS Encryption CLI. They represent recommended syntax in AWS Encryption CLI version 2.1.*x* and later.

New security features were originally released in AWS Encryption CLI versions 1.7.*x* and 2.0.*x*. However, AWS Encryption CLI version 1.8.*x* replaces version 1.7.*x* and AWS Encryption CLI 2.1.*x* replaces 2.0.*x*. For details, see the relevant [security advisory](https://github.com/aws/aws-encryption-sdk-cli/security/advisories/GHSA-2xwp-m7mq-7q3r) in the [aws-encryption-sdk-cli](https://github.com/aws/aws-encryption-sdk-cli/) repository on GitHub.

**Note**  
Unless noted in the parameter description, each parameter or attribute can be used only once in each command.  
If you use an attribute that a parameter does not support, the AWS Encryption CLI ignores that unsupported attribute without a warning or error.

**Get help**  
To get the full AWS Encryption CLI syntax with parameter descriptions, use `--help` or `-h`.  

```
aws-encryption-cli (--help | -h)
```

**Get the version**  
To get the version number of your AWS Encryption CLI installation, use `--version`. Be sure to include the version when you ask questions, report problems, or share tips about using the AWS Encryption CLI.  

```
aws-encryption-cli --version
```

**Encrypt data**  
The following syntax diagram shows the parameters that an **encrypt** command uses.   

```
aws-encryption-cli --encrypt
                   --input <input> [--recursive] [--decode]
                   --output <output> [--interactive] [--no-overwrite] [--suffix [<suffix>]] [--encode]
                   --wrapping-keys  [--wrapping-keys] ...
                       key=<keyID> [key=<keyID>] ...
                       [provider=<provider-name>] [region=<aws-region>] [profile=<aws-profile>]
                   --metadata-output <location> [--overwrite-metadata] | --suppress-metadata]
                   [--commitment-policy <commitment-policy>]
                   [--encryption-context <encryption_context> [<encryption_context> ...]]
                   [--max-encrypted-data-keys <integer>]
                   [--algorithm <algorithm_suite>]
                   [--caching <attributes>] 
                   [--frame-length <length>]
                   [-v | -vv | -vvv | -vvvv]
                   [--quiet]
```

**Decrypt data**  
The following syntax diagram shows the parameters that a **decrypt** command uses.   
In version 1.8.*x*, the `--wrapping-keys` parameter is optional when decrypting, but recommended. Beginning in version 2.1.*x*, the `--wrapping-keys` parameter is required when encrypting and decrypting. For AWS KMS keys, you can use the **key** attribute to specify wrapping keys (best practice) or set the **discovery** attribute to `true`, which doesn't limit the wrapping keys that the AWS Encryption CLI can use.  

```
aws-encryption-cli --decrypt (or [--decrypt-unsigned]) 
                   --input <input> [--recursive] [--decode]
                   --output <output> [--interactive] [--no-overwrite]  [--suffix [<suffix>]] [--encode]           
                   --wrapping-keys  [--wrapping-keys] ...
                       [key=<keyID>] [key=<keyID>] ...
                       [discovery={true|false}] [discovery-partition=<aws-partition-name> discovery-account=<aws-account-ID> [discovery-account=<aws-account-ID>] ...] 
                       [provider=<provider-name>] [region=<aws-region>] [profile=<aws-profile>]
                   --metadata-output <location> [--overwrite-metadata] | --suppress-metadata]
                   [--commitment-policy <commitment-policy>]
                   [--encryption-context <encryption_context> [<encryption_context> ...]]
                   [--buffer]
                   [--max-encrypted-data-keys <integer>]
                   [--caching <attributes>]
                   [--max-length <length>]
                   [-v | -vv | -vvv | -vvvv]
                   [--quiet]
```

**Use configuration files**  
You can refer to configuration files that contain parameters and their values. This is equivalent to typing the parameters and values in the command. For an example, see [How to store parameters in a configuration file](crypto-cli-how-to.md#crypto-cli-config-file).  

```
aws-encryption-cli @<configuration_file>

# In a PowerShell console, use a backtick to escape the @.
aws-encryption-cli `@<configuration_file>
```

## AWS Encryption CLI command line parameters
<a name="crypto-cli-parameters"></a>

This list provides a basic description of the AWS Encryption CLI command parameters. For a complete description, see the [aws-encryption-sdk-cli documentation](http://aws-encryption-sdk-cli.readthedocs.io/en/latest/).

**--encrypt (-e)**  
Encrypts the input data. Every command must have an `--encrypt`, or `--decrypt`, or `--decrypt-unsigned` parameter.

**--decrypt (-d)**  
Decrypts the input data. Every command must have an `--encrypt`, `--decrypt`, or `--decrypt-unsigned` parameter.

**--decrypt-unsigned [Introduced in versions 1.9.*x* and 2.2.*x*]**  
The `--decrypt-unsigned` parameter decrypts ciphertext and ensures that messages are unsigned before decryption. Use this parameter if you used the `--algorithm` parameter and selected an algorithm suite without digital signing to encrypt data. If the ciphertext is signed, decryption fails.  
You can use `--decrypt` or `--decrypt-unsigned` for decryption but not both.

**--wrapping-keys (-w) [Introduced in version 1.8.*x*]**  <a name="wrapping-keys"></a>
Specifies the [wrapping keys](concepts.md#master-key) (or *master keys*) used in encryption and decryption operations. You can use [multiple `--wrapping-keys` parameters](crypto-cli-how-to.md#cli-many-cmks) in each command.   
Beginning in version 2.1.*x*, the `--wrapping-keys` parameter is required in encrypt and decrypt commands. In version 1.8.*x*, encrypt commands require either a `--wrapping-keys` or `--master-keys` parameter. In version 1.8.*x* decrypt commands, a `--wrapping-keys` parameter is optional but recommended.   
When using a custom master key provider, encrypt and decrypt commands require **key** and **provider** attributes. When using AWS KMS keys, encrypt commands require a **key** attribute. Decrypt commands require a **key** attribute or a **discovery** attribute with a value of `true` (but not both). Using the **key** attribute when decrypting is an [AWS Encryption SDK best practice](best-practices.md). It is particularly important if you're decrypting batches of unfamiliar messages, such as those in an Amazon S3 bucket or an Amazon SQS queue.  
For an example showing how to use AWS KMS multi-Region keys as wrapping keys, see [Using multi-Region AWS KMS keys](configure.md#config-mrks).  
**Attributes**: The value of the `--wrapping-keys` parameter consists of the following attributes. The format is `attribute_name=value`.     
**key**  
Identifies the wrapping key used in the operation. The format is a **key**=ID pair. You can specify multiple **key** attributes in each `--wrapping-keys` parameter value.  
+ **Encrypt commands**: All encrypt commands require the **key** attribute . When you use an AWS KMS key in an encrypt command, the value of the **key** attribute can be a key ID, key ARN, an alias name, or an alias ARN. For descriptions of the AWS KMS key identifiers, see [Key identifiers](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id) in the *AWS Key Management Service Developer Guide*. 
+ **Decrypt commands**: When decrypting with AWS KMS keys, the `--wrapping-keys` parameter requires a **key** attribute with a [key ARN](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id-key-ARN) value or a **discovery** attribute with a value of `true` (but not both). Using the **key** attribute is an [AWS Encryption SDK best practice](best-practices.md). When decrypting with a custom master key provider, the **key** attribute is required.
**Note**  
To specify an AWS KMS wrapping key in a decrypt command, the value of the **key** attribute must be a key ARN. If you use a key ID, alias name, or alias ARN, the AWS Encryption CLI does not recognize the wrapping key.
You can specify multiple **key** attributes in each `--wrapping-keys` parameter value. However, any **provider**, **region**, and **profile** attributes in a `--wrapping-keys` parameter apply to all wrapping keys in that parameter value. To specify wrapping keys with different attribute values, use multiple `--wrapping-keys` parameters in the command.  
**discovery**  
Allows the AWS Encryption CLI to use any AWS KMS key to decrypt the message. The **discovery** value can be `true` or `false`. The default value is `false`. The **discovery** attribute is valid only in decrypt commands and only when the master key provider is AWS KMS.   
When decrypting with AWS KMS keys, the `--wrapping-keys` parameter requires a **key** attribute or a **discovery** attribute with a value of `true` (but not both). If you use the **key** attribute, you can use a **discovery** attribute with a value of `false` to explicitly reject discovery.   
+ `False` (default) — When the **discovery** attribute isn't specified or its value is `false`, the AWS Encryption CLI decrypts the message using only the AWS KMS keys specified by the **key** attribute of the `--wrapping-keys` parameter. If you don't specify a **key** attribute when discovery is `false`, the decrypt command fails. This value supports an AWS Encryption CLI [best practice](best-practices.md).
+ `True` — When the value of the **discovery** attribute is `true`, the AWS Encryption CLI gets the AWS KMS keys from metadata in the encrypted message, and uses those AWS KMS keys to decrypt the message. The **discovery** attribute with a value of `true` behaves like versions of the AWS Encryption CLI before version 1.8.*x* that didn't permit you to specify a wrapping key when decrypting. However, your intent to use any AWS KMS key is explicit. If you specify a **key** attribute when discovery is `true`, the decrypt command fails. 

  The `true` value might cause the AWS Encryption CLI to use AWS KMS keys in different AWS accounts and Regions, or attempt to use AWS KMS keys that the user isn't authorized to use. 
When **discovery** is `true`, it's a best practice to use the **discovery-partition** and **discovery-account** attributes to limit the AWS KMS keys used to those in the AWS accounts you specify.   
**discovery-account**  
Limits the AWS KMS keys used for decrypting to those in the specified AWS account. The only valid value for this attribute is an [AWS account ID](https://docs.aws.amazon.com/general/latest/gr/acct-identifiers.html).  
This attribute is optional and valid only in decrypt commands with AWS KMS keys where the **discovery** attribute is set to `true` and the **discovery-partition** attribute is specified.  
Each **discovery-account** attribute takes just one AWS account ID, but you can specify multiple **discovery-account** attributes in the same `--wrapping-keys` parameter. All accounts specified in a given `--wrapping-keys` parameter must be in the specified AWS partition.  
**discovery-partition**  
Specifies the AWS partition for the accounts in the **discovery-account** attribute. Its value must be an AWS partition, such as `aws`, `aws-cn`, or `aws-gov-cloud`. For information, see [Amazon Resource Names](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html#arns-syntax) in the *AWS General Reference*.  
This attribute is required when you use the **discovery-account** attribute. You can specify only one **discovery-partition** attribute in each `--wrapping keys` parameter. To specify AWS accounts in multiple partitions, use an additional `--wrapping-keys` parameter.  
**provider**  
Identifies the [master key provider](concepts.md#master-key-provider). The format is a **provider**=ID pair. The default value, **aws-kms**, represents AWS KMS. This attribute is required only when the master key provider is not AWS KMS.  
**region**  
Identifies the AWS Region of an AWS KMS key. This attribute is valid only for AWS KMS keys. It is used only when the **key** identifier does not specify a Region; otherwise, it is ignored. When it is used, it overrides the default Region in the AWS CLI named profile.   
**profile**  
Identifies an AWS CLI [named profile](https://docs.aws.amazon.com/cli/latest/userguide/cli-multiple-profiles.html). This attribute is valid only for AWS KMS keys. The Region in the profile is used only when the key identifier does not specify a Region and there is no **region** attribute in the command. 

**--input (-i)**  
Specifies the location of the data to encrypt or decrypt. This parameter is required. The value can be a path to a file or directory, or a file name pattern. If you are piping input to the command (stdin), use `-`.  
If the input does not exist, the command completes successfully without error or warning.    
**--recursive (-r, -R)**  
Performs the operation on files in the input directory and its subdirectories. This parameter is required when the value of `--input` is a directory.  
**--decode**  
Decodes Base64-encoded input.   
If you are decrypting a message that was encrypted and then encoded, you must decode the message before decrypting it. This parameter does that for you.   
For example, if you used the `--encode` parameter in an encrypt command, use the `--decode` parameter in the corresponding decrypt command. You can also use this parameter to decode Base64-encoded input before you encrypt it.

**--output (-o)**  
Specifies a destination for the output. This parameter is required. The value can be a file name, an existing directory, or `-`, which writes output to the command line (stdout).   
If the specified output directory does not exist, the command fails. If the input contains subdirectories, the AWS Encryption CLI reproduces the subdirectories under the output directory that you specify.   
By default, the AWS Encryption CLI overwrites files with the same name. To change that behavior, use the `--interactive` or `--no-overwrite` parameters. To suppress the overwrite warning, use the `--quiet` parameter.  
If a command that would overwrite an output file fails, the output file is deleted.  
**--interactive**  
Prompts before overwriting the file.  
**--no-overwrite**  
Does not overwrite files. Instead, if the output file exists, the AWS Encryption CLI skips the corresponding input.  
**--suffix**  
Specifies a custom file name suffix for files that the AWS Encryption CLI creates. To indicate no suffix, use the parameter with no value (`--suffix`).  
By default, when the `--output` parameter does not specify a file name, the output file name has the same name as the input file name plus the suffix. The suffix for encrypt commands is `.encrypted`. The suffix for decrypt commands is `.decrypted`.   
**--encode**  
Applies Base64 (binary to text) encoding to the output. Encoding prevents the shell host program from misinterpreting non-ASCII characters in output text.  
Use this parameter when writing encrypted output to stdout (`--output -`), especially in a PowerShell console, even when you are piping the output to another command or saving it in a variable.

**--metadata-output**  
Specifies a location for metadata about the cryptographic operations. Enter a path and file name. If the directory does not exist, the command fails. To write the metadata to the command line (stdout), use `-`.   
You cannot write command output (`--output`) and metadata output (`--metadata-output`) to stdout in the same command. Also, when the value of `--input` or `--output` is a directory (without file names), you cannot write the metadata output to the same directory or to any subdirectory of that directory.  
If you specify an existing file, by default, the AWS Encryption CLI appends new metadata records to any content in the file. This feature lets you create a single file that contains the metadata for all of your cryptographic operations. To overwrite the content in an existing file, use the `--overwrite-metadata` parameter.  
The AWS Encryption CLI returns a JSON-formatted metadata record for each encryption or decryption operation that the command performs. Each metadata record includes the full paths to the input and output file, the encryption context, the algorithm suite, and other valuable information that you can use to review the operation and verify that it meets your security standards.    
**--overwrite-metadata**  
Overwrites the content in the metadata output file. By default, the `--metadata-output` parameter appends metadata to any existing content in the file.

**--suppress-metadata (-S)**  
Suppresses the metadata about the encryption or decryption operation. 

**--commitment-policy**  <a name="syntax-commitment-policy"></a>
Specifies the [commitment policy](concepts.md#commitment-policy) for encrypt and decrypt commands. The commitment policy determines whether your message is encrypted and decrypted with the [key commitment](concepts.md#key-commitment) security feature.  
The `--commitment-policy` parameter is introduced in version 1.8.*x*. It is valid in encrypt and decrypt commands.  
**In version 1.8.*x***, the AWS Encryption CLI uses the `forbid-encrypt-allow-decrypt` commitment policy for all encrypt and decrypt operations. When you use the `--wrapping-keys` parameter in an encrypt or decrypt command, a `--commitment-policy` parameter with the `forbid-encrypt-allow-decrypt` value is required. If you don't use the `--wrapping-keys` parameter, the `--commitment-policy` parameter is invalid. Setting a commitment policy explicitly prevents your commitment policy from changing automatically to `require-encrypt-require-decrypt` when you upgrade to version 2.1.*x*  
Beginning in **version 2.1.*x***, all commitment policy values are supported. The `--commitment-policy` parameter is optional and the default value is `require-encrypt-require-decrypt`.   
This parameter has the following values:  
+ `forbid-encrypt-allow-decrypt` — Cannot encrypt with key commitment. It can decrypt ciphertexts encrypted with or without key commitment. 

  In version 1.8.*x*, this is the only valid value. The AWS Encryption CLI uses the `forbid-encrypt-allow-decrypt` commitment policy for all encrypt and decrypt operations. 
+ `require-encrypt-allow-decrypt` — Encrypts only with key commitment. Decrypts with and without key commitment. This value is introduced in version 2.1.*x*.
+ `require-encrypt-require-decrypt` (default) — Encrypts and decrypts only with key commitment. This value is introduced in version 2.1.*x*. It is the default value in versions 2.1.*x* and later. With this value, the AWS Encryption CLI will not decrypt any ciphertext that was encrypted with earlier versions of the AWS Encryption SDK.
For detailed information about setting your commitment policy, see [Migrating your AWS Encryption SDK](migration.md).

**--encryption-context (-c)**  
Specifies an [encryption context](crypto-cli-how-to.md#crypto-cli-encryption-context) for the operation. This parameter is not required, but it is recommended.   
+ In an `--encrypt` command, enter one or more `name=value` pairs. Use spaces to separate the pairs.
+ In a `--decrypt` command, enter `name=value` pairs, `name` elements with no values, or both.
If the `name` or `value` in a `name=value` pair includes spaces or special characters, enclose the entire pair in quotation marks. For example, `--encryption-context "department=software development"`.

**--buffer (-b) [Introduced in versions 1.9.*x* and 2.2.*x*]**  
Returns plaintext only after all input is processed, including verifying the digital signature if one is present.

**--max-encrypted-data-keys [Introduced in versions 1.9.*x* and 2.2.*x*]**  
Specifies the maximum number of encrypted data keys in an encrypted message. This parameter is optional.   
Valid values are 1 – 65,535. If you omit this parameter, the AWS Encryption CLI does not enforce any maximum. An encrypted message can hold up to 65,535 (2^16 - 1) encrypted data keys.  
You can use this parameter in encrypt commands to prevent a malformed message. You can use it in decrypt commands to detect malicious messages and avoid decrypting messages with numerous encrypted data keys that you can't decrypt. For details and an example, see [Limiting encrypted data keys](configure.md#config-limit-keys).

**--help (-h)**  
Prints usage and syntax at the command line.

**--version**  
Gets the version of the AWS Encryption CLI.

**-v \$1 -vv \$1 -vvv \$1 -vvvv**  
Displays verbose information, warning, and debugging messages. The detail in the output increases with the number of `v`s in the parameter. The most detailed setting (`-vvvv`) returns debugging-level data from the AWS Encryption CLI and all of the components that it uses.

**--quiet (-q)**  
Suppresses warning messages, such as the message that appears when you overwrite an output file.

**--master-keys (-m) [Deprecated]**  
The --master-keys parameter is deprecated in 1.8.*x* and removed in version 2.1.*x*. Instead, use the [--wrapping-keys](#wrapping-keys) parameter.
Specifies the [master keys](concepts.md#master-key) used in encryption and decryption operations. You can use multiple master keys parameters in each command.  
The `--master-keys` parameter is required in encrypt commands. It is required in decrypt commands only when you are using a custom (non-AWS KMS) master key provider.  
**Attributes**: The value of the `--master-keys` parameter consists of the following attributes. The format is `attribute_name=value`.     
**key**  
Identifies the [wrapping key](concepts.md#master-key) used in the operation. The format is a **key**=ID pair. The **key** attribute is required in all encrypt commands.   
When you use an AWS KMS key in an encrypt command, the value of the **key** attribute can be a key ID, key ARN, an alias name, or an alias ARN. For details about AWS KMS key identifiers, see [Key identifiers](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id) in the *AWS Key Management Service Developer Guide*.  
The **key** attribute is required in decrypt commands when the master key provider is not AWS KMS. The **key** attribute is not permitted in commands that decrypt data that was encrypted under an AWS KMS key.   
You can specify multiple **key** attributes in each `--master-keys` parameter value. However, any **provider**, **region**, and **profile** attributes apply to all master keys in the parameter value. To specify master keys with different attribute values, use multiple `--master-keys` parameters in the command.   
**provider**  
Identifies the [master key provider](concepts.md#master-key-provider). The format is a **provider**=ID pair. The default value, **aws-kms**, represents AWS KMS. This attribute is required only when the master key provider is not AWS KMS.  
**region**  
Identifies the AWS Region of an AWS KMS key. This attribute is valid only for AWS KMS keys. It is used only when the **key** identifier does not specify a Region; otherwise, it is ignored. When it is used, it overrides the default Region in the AWS CLI named profile.   
**profile**  
Identifies an AWS CLI [named profile](https://docs.aws.amazon.com/cli/latest/userguide/cli-multiple-profiles.html). This attribute is valid only for AWS KMS keys. The Region in the profile is used only when the key identifier does not specify a Region and there is no **region** attribute in the command. 

## Advanced parameters
<a name="cli-advanced-parameters"></a>

**--algorithm**  
Specifies an alternate [algorithm suite](concepts.md#crypto-algorithm). This parameter is optional and valid only in encrypt commands.   
If you omit this parameter, the AWS Encryption CLI uses one of the default algorithm suites for the AWS Encryption SDK introduced in version 1.8.*x*. Both default algorithms use AES-GCM with an [HKDF](https://en.wikipedia.org/wiki/HKDF), an ECDSA signature, and a 256-bit encryption key. One uses key commitment; one does not. The choice of default algorithm suite is determined by the [commitment policy](concepts.md#commitment-policy) for the command.  
The default algorithm suites are recommended for most encryption operations. For a list of valid values, see the values for the `algorithm` parameter in [Read the Docs](https://aws-encryption-sdk-cli.readthedocs.io/en/latest/index.html#execution).

**--frame-length**  
Creates output with specified frame length. This parameter is optional and valid only in encrypt commands.   
Enter a value in bytes. Valid values are 0 and 1 – 2^31 - 1. A value of 0 indicates nonframed data. The default is 4096 (bytes).   
Whenever possible, use framed data. The AWS Encryption SDK supports nonframed data only for legacy use. Some language implementations of the AWS Encryption SDK can still generate nonframed ciphertext. All supported language implementations can decrypt framed and nonframed ciphertext.

**--max-length**  
Indicates the maximum frame size (or maximum content length for nonframed messages) in bytes to read from encrypted messages. This parameter is optional and valid only in decrypt commands. It is designed to protect you from decrypting extremely large malicious ciphertext.   
Enter a value in bytes. If you omit this parameter, the AWS Encryption SDK does not limit the frame size when decrypting.

**--caching**  
Enables the [data key caching](data-key-caching.md) feature, which reuses data keys, instead of generating a new data key for each input file. This parameter supports an advanced scenario. Be sure to read the [Data Key Caching](data-key-caching.md) documentation before using this feature.   
The `--caching` parameter has the following attributes.    
**capacity (required)**  
Determines the maximum number of entries in the cache.   
The minimum value is 1. There is no maximum value.  
**max\$1age (required)**  
Determine how long cache entries are used, in seconds, beginning when they are added to the cache.  
Enter a value greater than 0. There is no maximum value.  
**max\$1messages\$1encrypted (optional)**  
Determines the maximum number of messages that a cached entry can encrypt.   
Valid values are 1 – 2^32. The default value is 2^32 (messages).  
**max\$1bytes\$1encrypted (optional)**  
Determines the maximum number of bytes that a cached entry can encrypt.  
Valid values are 0 and 1 – 2^63 - 1. The default value is 2^63 - 1 (messages). A value of 0 lets you use data key caching only when you are encrypting empty message strings.

# Versions of the AWS Encryption CLI
<a name="crypto-cli-versions"></a>

We recommend that you use the latest version of the AWS Encryption CLI.

**Note**  
Versions of the AWS Encryption CLI earlier than 4.0.0 are in the [end-of-support phase](https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html#version-life-cycle).  
You can safely update from version 2.1.*x* and later to the latest version of the AWS Encryption CLI without any code or data changes. However, [ new security features](about-versions.md#version-2) introduced in version 2.1.*x* are not backward-compatible. To update from version 1.7.*x* or earlier, you must first update to the latest 1.*x* version of the AWS Encryption CLI. For details, see [Migrating your AWS Encryption SDK](migration.md).  
New security features were originally released in AWS Encryption CLI versions 1.7.*x* and 2.0.*x*. However, AWS Encryption CLI version 1.8.*x* replaces version 1.7.*x* and AWS Encryption CLI 2.1.*x* replaces 2.0.*x*. For details, see the relevant [security advisory](https://github.com/aws/aws-encryption-sdk-cli/security/advisories/GHSA-2xwp-m7mq-7q3r) in the [aws-encryption-sdk-cli](https://github.com/aws/aws-encryption-sdk-cli/) repository on GitHub.

For information about significant versions of the AWS Encryption SDK, see [Versions of the AWS Encryption SDK](about-versions.md).

**Which version do I use?**

If you're new to the AWS Encryption CLI, use the latest version.

To decrypt data encrypted by a version of the AWS Encryption SDK earlier than version 1.7.*x*, migrate first to the latest version of the AWS Encryption CLI. Make [all recommended changes](migration-guide.md) before updating to version 2.1.*x* or later. For details, see [Migrating your AWS Encryption SDK](migration.md).

**Learn more**
+ For detailed information about the changes and guidance for migrating to these new versions, see [Migrating your AWS Encryption SDK](migration.md).
+ For descriptions of the new AWS Encryption CLI parameters and attributes, see [AWS Encryption SDK CLI syntax and parameter reference](crypto-cli-reference.md).

The following lists describe the change to the AWS Encryption CLI in versions 1.8.*x* and 2.1.*x*.

## Version 1.8.*x* changes to the AWS Encryption CLI
<a name="cli-changes-1.7"></a>
+ Deprecates the `--master-keys` parameter. Instead, use the `--wrapping-keys` parameter.
+ Adds the `--wrapping-keys` (`-w`) parameter. It supports all attributes of the `--master-keys` parameter. It also adds the following optional attributes, which are valid only when decrypting with AWS KMS keys.
  + **discovery**
  + **discovery-partition**
  + **discovery-account**

  For custom master key providers, `--encrypt` and -`-decrypt` commands require either a `--wrapping-keys` parameter or a `--master-keys` parameter (but not both). Also, an `--encrypt` command with AWS KMS keys requires either a `--wrapping-keys` parameter or a `--master-keys` parameter (but not both). 

  In a `--decrypt` command with AWS KMS keys, the `--wrapping-keys` parameter is optional, but recommended, because it is required in version 2.1.*x*. If you use it, you must specify either the **key** attribute or the **discovery** attribute with a value of `true` (but not both).
+ Adds the `--commitment-policy` parameter. The only valid value is `forbid-encrypt-allow-decrypt`. The `forbid-encrypt-allow-decrypt` commitment policy is used in all encrypt and decrypt commands.

  In version 1.8.*x*, when you use the `--wrapping-keys` parameter, a `--commitment-policy` parameter with the `forbid-encrypt-allow-decrypt` value is required. Setting the value explicitly prevents your [commitment policy](concepts.md#commitment-policy) from changing automatically to `require-encrypt-require-decrypt` when you upgrade to version 2.1.*x*.

## Version 2.1.*x* changes to the AWS Encryption CLI
<a name="cli-changes-2.x"></a>
+ Removes the `--master-keys` parameter. Instead, use the `--wrapping-keys` parameter.
+ The `--wrapping-keys` parameter is required in all encrypt and decrypt commands. You must specify either a **key** attribute or a **discovery** attribute with a value of `true` (but not both).
+ The `--commitment-policy` parameter supports the following values. For details, see [Setting your commitment policy](migrate-commitment-policy.md).
  + `forbid-encrypt-allow-decrypt`
  + `require-encrypt-allow-decrypt`
  + `require-encrypt-require decrypt` (Default)
+ The `--commitment-policy` parameter is optional in version 2.1.*x*. The default value is `require-encrypt-require-decrypt`.

## Version 1.9.*x* and 2.2.*x* changes to the AWS Encryption CLI
<a name="cli-changes-2.2"></a>
+ Adds the `--decrypt-unsigned` parameter. For details, see [Version 2.2.*x*](about-versions.md#version2.2.x).
+ Adds the `--buffer` parameter. For details, see [Version 2.2.*x*](about-versions.md#version2.2.x).
+ Adds the `--max-encrypted-data-keys` parameter. For details, see [Limiting encrypted data keys](configure.md#config-limit-keys).

## Version 3.0.*x* changes to the AWS Encryption CLI
<a name="cli-changes-v3"></a>
+ Adds support for AWS KMS multi-Region keys. For details, see [Using multi-Region AWS KMS keys](configure.md#config-mrks).