

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# AWS Encryption SDK 编程语言
<a name="programming-languages"></a>

 AWS Encryption SDK 适用于以下编程语言。所有语言实施都是可互操作的。您可以使用一种语言实施进行加密，并使用另一种语言实施进行解密。互操作性可能受到语言约束的限制。如果是这样，这些约束将在有关语言实施的主题中进行描述。此外，在加密和解密时，必须使用兼容的密钥环或主密钥和主密钥提供程序。有关详细信息，请参阅[密钥环兼容性](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)
+ [命令行界面](crypto-cli.md)

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

为使用 C 语言编写应用程序的开发人员 AWS Encryption SDK for C 提供了一个客户端加密库。它也是用更高级编程语言实现 AWS Encryption SDK 的基础。

与的所有实现一样 AWS Encryption SDK， AWS Encryption SDK for C 提供了高级数据保护功能。这些功能包括[信封加密](concepts.md#envelope-encryption)、其他经过身份验证的数据 (AAD) 以及安全、经过身份验证且对称的密钥[算法套件](concepts.md#crypto-algorithm)，如具有密钥派生和签名的 256 位 AES-GCM。

的所有特定于语言的实现 AWS Encryption SDK 都是完全可互操作的。例如，您可以使用加密数据， AWS Encryption SDK for C 并使用[任何支持的语言实现](programming-languages.md)对其进行解密，包括加密 [AWS CLI](crypto-cli.md)。

 AWS Encryption SDK for C 要求与 AWS Key Management Service (AWS KMS) 适用于 C\$1\$1 的 AWS SDK 进行交互。仅当您使用可选的 [AWS KMS 密钥环](use-kms-keyring.md)时，才需要使用该工具。但是， AWS Encryption SDK 不需要 AWS KMS 或任何其他 AWS 服务。

**了解更多**
+ 有关使用编程的详细信息 AWS Encryption SDK for C，请参阅 [C 示](c-examples.md)[例 GitHub、上[aws-encryption-sdk-c 存储库](https://github.com/aws/aws-encryption-sdk-c/)中的示例](https://github.com/aws/aws-encryption-sdk-c/tree/master/examples)以及 [AWS Encryption SDK for C API 文档](https://aws.github.io/aws-encryption-sdk-c/html/)。
+ 有关如何使用加密数据以便可以将其解密为多个区域的讨论 AWS 区域，请参阅安全[博客中的如何使用 C 语言解密多个区域中的密文](https://aws.amazon.com/blogs/security/how-to-decrypt-ciphertexts-multiple-regions-aws-encryption-sdk-in-c/)。 AWS Encryption SDK for C AWS Encryption SDK AWS 

**Topics**
+ [安装](c-language-installation.md)
+ [使用 C 开发工具包](c-language-using.md)
+ [示例](c-examples.md)

# 正在安装 AWS Encryption SDK for C
<a name="c-language-installation"></a>

安装最新版本的 AWS Encryption SDK for C。

**注意**  
[2.0.0 AWS Encryption SDK for C 之前的所有版本都处于该阶段。end-of-support](https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html#version-life-cycle)  
您可以安全地从 AWS Encryption SDK for C 版本 2.0.*x* 及更高版本更新为最新版本，无需更改任何代码或数据。但是，版本 2.0.*x* 中引入了[新的安全功能](about-versions.md#version-2)，不向后兼容。要从 1.7.*x* 之前的版本更新到 2.0.*x* 及更高版本，必须先更新到 AWS Encryption SDK for C最新版本 1.*x*。有关更多信息，请参阅 [迁移你的 AWS Encryption SDK](migration.md)。

您可以在[aws-encryption-sdk-c](https://github.com/aws/aws-encryption-sdk-c/)存储库的 [README 文件 AWS Encryption SDK for C](https://github.com/aws/aws-encryption-sdk-c/#readme)中找到有关安装和构建的详细说明。其中包括在 Amazon Linux、Ubuntu、macOS 和 Windows 平台上进行构建的说明。

开始之前，请决定是否要在 AWS Encryption SDK中使用 [AWS KMS 密钥环](use-kms-keyring.md)。如果您使用 AWS KMS 钥匙圈，则需要安装。 适用于 C\$1\$1 的 AWS SDK需要使用 AWS SDK 才能与 [AWS Key Management Service](https://docs.aws.amazon.com/kms/latest/developerguide/)(AWS KMS) 进行交互。使用 AWS KMS 密钥环时， AWS Encryption SDK AWS KMS 用于生成和保护保护数据的加密密钥。

 适用于 C\$1\$1 的 AWS SDK 如果您使用的是其他密钥环类型，例如原始的 AES 密钥环、原始 RSA 密钥环或不包含密钥环的多密钥环，则无需安装。 AWS KMS 但是，使用原始密钥环类型时，您需要生成并保护自己的原始包装密钥。

如果您在安装时遇到问题，请在 `aws-encryption-sdk-c` 存储库中[提交问题](https://github.com/aws/aws-encryption-sdk-c/issues)或使用此页面上的任何反馈链接。

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

本主题解释了其他编程语言实现中不支持的某些功能。 AWS Encryption SDK for C 

本节中的示例说明了如何使用 AWS Encryption SDK for C[版本 2.0.*x*](about-versions.md) 及更高版本。有关使用早期版本的示例，请在[aws-encryption-sdk-c 存储库存储库](https://github.com/aws/aws-encryption-sdk-c/)的[版本](https://github.com/aws/aws-encryption-sdk-c/releases)列表中找到您的版本 GitHub。

有关使用编程的详细信息 AWS Encryption SDK for C，请参阅 [C 示](c-examples.md)[例 GitHub、上[aws-encryption-sdk-c 存储库](https://github.com/aws/aws-encryption-sdk-c/)中的示例](https://github.com/aws/aws-encryption-sdk-c/tree/master/examples)以及 [AWS Encryption SDK for C API 文档](https://aws.github.io/aws-encryption-sdk-c/html/)。

另请参阅：[密钥环](choose-keyring.md)

**Topics**
+ [

## 加密和解密数据的模式
](#c-language-using-pattern)
+ [

## 引用计数
](#c-language-using-release)

## 加密和解密数据的模式
<a name="c-language-using-pattern"></a>

使用时 AWS Encryption SDK for C，将遵循类似于以下的模式：创建[密钥环，创建使用密钥环](concepts.md#keyring)的 [CMM](concepts.md#crypt-materials-manager)，创建使用 CMM（和密钥环）的会话，然后处理会话。

1. 加载错误字符串。  
在 C 或 C\$1\$1 代码中调用 `aws_cryptosdk_load_error_strings()` 方法。该方法加载对调试非常有用的错误信息。  
您只需要调用一次，例如在 `main` 方法中调用。  

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

2. 创建一个密钥环。  
使用要用于加密数据密钥的包装密钥配置[密钥环](concepts.md#keyring)。此示例使用带[AWS KMS 钥匙圈](use-kms-keyring.md)的密钥环 AWS KMS key，但您可以使用任何类型的密钥环代替它。  
要 AWS KMS key 在中的加密密钥环中识别 AWS Encryption SDK for C，请指定[密钥 ARN](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id-key-ARN) 或[别名](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id-alias-arn) ARN。在解密密钥环中，您必须使用密钥 ARN。有关更多信息，请参阅 [在 AWS KMS 钥匙圈 AWS KMS keys 中识别](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. 创建会话。  
在中 AWS Encryption SDK for C，您可以使用*会话*来加密一条纯文本消息或解密一条密文消息，无论其大小如何。会话在整个处理过程中维护消息的状态。  
使用分配器、密钥环和模式（`AWS_CRYPTOSDK_ENCRYPT` 或 `AWS_CRYPTOSDK_DECRYPT`）配置会话。如果需要更改会话模式，请使用 `aws_cryptosdk_session_reset` 方法。  
当您使用密钥环创建会话时， AWS Encryption SDK for C 会自动为您创建默认的加密材料管理器 (CMM)。您无需创建、维护或销毁该对象。  
例如，以下会话使用分配器以及在步骤 1 中定义的密钥环。在加密数据时，模式为 `AWS_CRYPTOSDK_ENCRYPT`。  

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

4. 加密或解密数据。  
要处理会话中的数据，请使用 `aws_cryptosdk_session_process` 方法。如果输入缓冲区足够大，可以存放整个明文，并且输出缓冲区足够大，可以存放整个加密文字，则可以调用 `aws_cryptosdk_session_process_full`。不过，如果需要处理串流数据，您可以循环调用 `aws_cryptosdk_session_process`。有关示例，请参阅 [file\$1streaming.cpp](https://github.com/aws/aws-encryption-sdk-c/blob/master/examples/file_streaming.cpp) 示例。`aws_cryptosdk_session_process_full`在 1.9 AWS Encryption SDK 版本中引入。 *x* 和 2.2。 *x*。  
将会话配置为加密数据时，明文字段描述输入，密文字段描述输出。`plaintext` 字段包含要加密的消息，`ciphertext` 字段接收加密方法返回的[加密的消息](message-format.md)。  

```
/* Encrypting data */
aws_cryptosdk_session_process_full(session,
                                   ciphertext,
                                   ciphertext_buffer_size,
                                   &ciphertext_length,
                                   plaintext,
                                   plaintext_length)
```
将会话配置为解密数据时，密文字段描述输入，明文字段描述输出。`ciphertext` 字段包含加密方法返回的[加密的消息](message-format.md)，`plaintext` 字段接收解密方法返回的明文消息。  
要解密数据，请调用 `aws_cryptosdk_session_process_full` 方法。  

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

## 引用计数
<a name="c-language-using-release"></a>

为了防止内存泄漏，在使用完创建的所有对象时，请务必释放对它们的引用。否则，可能会造成内存泄漏。本开发工具包提供了简化该任务的方法。

每次使用一个以下子对象创建父对象时，父对象都会获取并保持对该子对象的引用，如下所示：
+ [密钥环](concepts.md#keyring)，例如，使用密钥环创建会话
+ 默认[加密材料管理器](concepts.md#crypt-materials-manager)（CMM），例如，使用默认 CMM 创建会话或自定义 CMM
+ [数据密钥缓存](data-key-caching.md)，例如，使用密钥环和缓存创建缓存 CMM

除非需要对子对象进行单独的引用，否则，您可以在创建父对象后立即释放对子对象的引用。在销毁父对象时，将释放对子对象的其余引用。该模式确保您只在需要时维护对每个对象的引用，不会因为未释放的引用而造成内存泄漏。

您仅负责释放对您明确创建的子对象的引用。您不负责管理对该开发工具包创建的任何对象的引用。如果该软件开发工具包创建一个对象（例如，`aws_cryptosdk_caching_cmm_new_from_keyring` 方法添加到会话中的默认 CMM），该软件开发工具包将管理该对象及其引用的创建和销毁过程。

在以下示例中，在使用[密钥环](concepts.md#keyring)创建会话时，会话将获取对密钥环的引用并保持该引用，直到销毁会话为止。如果不需要保持对密钥环的其他引用，您可以在创建会话后立即使用 `aws_cryptosdk_keyring_release` 方法释放密钥环对象。该方法将减少密钥环的引用计数。在调用 `aws_cryptosdk_session_destroy` 以销毁会话时，将释放会话对密钥环的引用。

```
// 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);
```

对于更复杂的任务（例如，将密钥环重复用于多个会话或在 CMM 中指定算法套件），您可能需要保持对该对象的单独引用。如果是这样，请不要立即调用 release 方法，而是在不再使用这些对象时，除了销毁会话以外，还要释放引用。

当您使用其他方法（例如缓存 CMM）进行[数据密钥缓](data-key-caching.md)存时 CMMs，这种引用计数技术也适用。从缓存和密钥环中创建缓存 CMM 时，缓存 CMM 将获取对两个对象的引用。除非您需要使用这些 CMM 执行其他任务，否则，您可以在创建缓存 CMM 后立即释放对缓存和密钥环的单独引用。然后，在使用缓存 CMM 创建会话时，您可以释放对缓存 CMM 的引用。

请注意，您仅负责释放对您明确创建的对象的引用。方法创建的对象（例如，作为缓存 CMM 基础的默认 CMM）是由该方法管理的。

```
/ 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 例子
<a name="c-examples"></a>

以下示例向您展示了如何使用 AWS Encryption SDK for C 来加密和解密数据。

本节中的示例说明了如何使用版本 2.0.*x* 及更高版本的 AWS Encryption SDK for C。有关使用早期版本的示例，请在[aws-encryption-sdk-c 存储库存储库](https://github.com/aws/aws-encryption-sdk-c/)的[版本](https://github.com/aws/aws-encryption-sdk-c/releases)列表中找到您的版本 GitHub。

安装和构建时 AWS Encryption SDK for C，这些示例和其他示例的源代码包含在`examples`子目录中，它们会被编译并内置到该`build`目录中。您也可以在上[aws-encryption-sdk-c](https://github.com/aws/aws-encryption-sdk-c/) GitHub存储库的[示例](https://github.com/aws/aws-encryption-sdk-c/tree/master/examples)子目录中找到它们。

**Topics**
+ [

## 加密和解密字符串
](#c-example-strings)

## 加密和解密字符串
<a name="c-example-strings"></a>

以下示例向您展示了如何使用 AWS Encryption SDK for C 来加密和解密字符串。

此示例以[AWS KMS 密钥环](use-kms-keyring.md)为特色，这是一种使用 AWS KMS key in [AWS Key Management Service (AWS KMS)](https://docs.aws.amazon.com/kms/latest/developerguide/) 生成和加密数据密钥的密钥环。该示例包括用 C\$1\$1 编写的代码。使用 AWS KMS 钥匙圈 AWS KMS 时 AWS Encryption SDK for C 适用于 C\$1\$1 的 AWS SDK 需要调用。如果您使用的是不与之交互的密钥环 AWS KMS，例如原始的 AES 密钥环、未处理的 RSA 密钥环或不包含密钥环的多密钥环，则 AWS KMS 不需要使用。 适用于 C\$1\$1 的 AWS SDK 

有关创建的帮助 AWS KMS key，请参阅《*AWS Key Management Service 开发者指南》*中的[创建密钥](https://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html)。有关识别 AWS KMS 钥匙圈 AWS KMS keys 中的的帮助，请参阅[在 AWS KMS 钥匙圈 AWS KMS keys 中识别](use-kms-keyring.md#kms-keyring-id)。

**请参阅完整的代码示例**：[string.cpp](https://github.com/aws/aws-encryption-sdk-c/blob/master/examples/string.cpp)

**Topics**
+ [

### 加密字符串
](#c-example-string-encrypt)
+ [

### 解密字符串
](#c-example-string-decrypt)

### 加密字符串
<a name="c-example-string-encrypt"></a>

本示例的第一部分使用带有密钥环的 AWS KMS 密钥环 AWS KMS key 来加密纯文本字符串。

步骤 1：加载错误字符串。  
在 C 或 C\$1\$1 代码中调用 `aws_cryptosdk_load_error_strings()` 方法。该方法加载对调试非常有用的错误信息。  
您只需要调用一次，例如在 `main` 方法中调用。  

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

步骤 2：构造密钥环。  
创建用于加密的 AWS KMS 密钥环。本示例中的密钥环配置为一个 AWS KMS key，但您可以将多个密钥环配置为多个 AWS KMS 密钥环 AWS KMS keys，包括在不同 AWS 区域 和不同的账户 AWS KMS keys 中。  
要 AWS KMS key 在中的加密密钥环中识别 AWS Encryption SDK for C，请指定[密钥 ARN](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id-key-ARN) 或[别名](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id-alias-arn) ARN。在解密密钥环中，您必须使用密钥 ARN。有关更多信息，请参阅 [在 AWS KMS 钥匙圈 AWS KMS keys 中识别](use-kms-keyring.md#kms-keyring-id)。  
[在 AWS KMS 钥匙圈 AWS KMS keys 中识别](use-kms-keyring.md#kms-keyring-id)  
创建包含多个密钥的密钥环时 AWS KMS keys，可以指定 AWS KMS key 用于生成和加密纯文本数据密钥的，以及用于加密相同纯文本数据密钥的可选附加 AWS KMS keys 数组。在这种情况下，您只需要指定生成器 AWS KMS key。  
在运行该代码之前，请将示例密钥 ARN 替换为有效 ARN。  

```
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：创建会话。  
使用分配器、模式枚举器和密钥环创建一个会话。  
每个会话都需要一种模式：用于加密的 `AWS_CRYPTOSDK_ENCRYPT` 或用于解密的 `AWS_CRYPTOSDK_DECRYPT`。要更改现有会话的模式，请使用 `aws_cryptosdk_session_reset` 方法。  
在使用密钥环创建一个会话后，您可以使用该开发工具包提供的方法释放对密钥环的引用。该会话在生命周期内保留对密钥环对象的引用。在销毁该会话时，将释放对密钥环和会话对象的引用。这种[引用计数](c-language-using.md#c-language-using-release)方法有助于防止内存泄漏，并防止在使用对象时将其释放。  

```
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);
```

步骤 4：设置加密上下文。  
[加密上下文](concepts.md#encryption-context)是任意的非机密其他经过身份验证的数据。当您提供有关加密的加密上下文时，会 AWS Encryption SDK 以加密方式将加密上下文绑定到密文，因此解密数据需要相同的加密上下文。使用加密上下文是可选的，但作为一项最佳实践，建议您提供加密上下文。  
首先，创建一个包含加密上下文字符串的哈希表。  

```
/* 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)
```
获取会话中加密上下文的可变指针。然后，使用 `aws_cryptosdk_enc_ctx_clone` 函数将加密上下文复制到会话中。请将副本保留在 `my_enc_ctx` 中，以便在解密数据后验证该值。  
加密上下文是会话的一部分，而不是传递给会话进程函数的参数。这可保证对消息的每个分段使用相同的加密上下文，即使多次调用会话进程函数来加密整个消息也是如此。  

```
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)
```

步骤 5：加密字符串。  
要加密明文字符串，请使用 `aws_cryptosdk_session_process_full` 方法和使用加密模式的会话。此方法在 1.9 AWS Encryption SDK 版本中引入。 *x* 和 2.2。 *x*，专为非流式加密和解密而设计。要处理串流数据，请在循环中调用 `aws_cryptosdk_session_process`。  
加密时，明文字段为输入字段；密文字段为输出字段。处理完成后，`ciphertext_output` 字段包含[加密的消息](concepts.md#message)，其中包括实际密文、加密的数据密钥和加密上下文。您可以对任何支持的编程语言使用来解密此加密消息。 AWS Encryption SDK   

```
/* 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;
}
```

步骤6：清理会话。  
最后一步将销毁会话，包括对 CMM 和密钥环的引用。  
您也可以根据需要重复使用具有相同密钥环和 CMM 的会话来解密字符串，或加密/解密其他消息，而不是销毁会话。要使用会话进行解密，请使用 `aws_cryptosdk_session_reset` 方法将模式更改为 `AWS_CRYPTOSDK_DECRYPT`。

### 解密字符串
<a name="c-example-string-decrypt"></a>

本示例的第二部分将对包含原始字符串密文的加密消息进行解密。

步骤 1：加载错误字符串。  
在 C 或 C\$1\$1 代码中调用 `aws_cryptosdk_load_error_strings()` 方法。该方法加载对调试非常有用的错误信息。  
您只需要调用一次，例如在 `main` 方法中调用。  

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

步骤 2：构造密钥环。  
当你解密数据时 AWS KMS，你会传入加密 API [返回的加密消息](concepts.md#message)。[解密 API](https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.html) 不以输入 AWS KMS key 为输入。相反， AWS KMS 使用与加密密文相同的方法 AWS KMS key 来解密密文。但是， AWS Encryption SDK 允许您使用加密和解密来 AWS KMS keys 指定密 AWS KMS 钥环。  
在解密时，您可以仅使用要用于解密加密消息 AWS KMS keys 的密钥环来配置密钥环。例如，您可能想创建一个仅包含组织中特定角色使用的密钥环。 AWS KMS key AWS KMS key 除非它出现在解密密钥环中，否则永远不会使用它。 AWS Encryption SDK 如果 SDK 无法使用您提供的密钥环 AWS KMS keys 中的来解密加密的数据密钥，要么是因为密钥环 AWS KMS keys 中没有使用任何数据密钥来加密任何数据密钥，要么是因为调用者无权使用密钥环 AWS KMS keys 中的进行解密，则解密调用将失败。  
 AWS KMS key [为解密密钥环指定时，必须使用其密钥 ARN。](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id-key-ARN)仅允许 ARNs在加密密钥环中使用@@ [别名](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id-alias-arn)。有关识别 AWS KMS 钥匙圈 AWS KMS keys 中的的帮助，请参阅[在 AWS KMS 钥匙圈 AWS KMS keys 中识别](use-kms-keyring.md#kms-keyring-id)。  
在此示例中，我们指定了一个密钥环，该密钥环配置为 AWS KMS key 用于加密字符串的密钥环。在运行该代码之前，请将示例密钥 ARN 替换为有效 ARN。  

```
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：创建会话。  
使用分配器和密钥环创建一个会话。要配置解密会话，请使用 `AWS_CRYPTOSDK_DECRYPT` 模式配置会话。  
在使用密钥环创建一个会话后，您可以使用该开发工具包提供的方法释放对密钥环的引用。该会话在生命周期内保留对密钥环对象的引用，在销毁该会话时，将会释放会话和密钥环。这种引用计数方法有助于防止内存泄漏，并防止在使用对象时将其释放。  

```
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);
```

步骤 4：解密字符串。  
要解密字符串，请使用 `aws_cryptosdk_session_process_full` 方法和配置用于解密的会话。此方法在 AWS Encryption SDK 版本 1.9.*x* 和 2.2.*x* 中引入，专为非串流加密和解密而设计。要处理串流数据，请在循环中调用 `aws_cryptosdk_session_process`。  
解密时，密文字段为输入字段，明文字段是输出字段。`ciphertext_input` 字段包含加密方法返回的[加密消息](message-format.md)。处理完成后，`plaintext_output` 字段包含明文（解密后的）字符串。  

```
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;
}
```

步骤 5：验证加密上下文。  
请确保实际的加密上下文（用于解密消息的上下文）包含您在加密消息时提供的加密上下文。实际加密上下文可能包含额外的键值对，因为[加密材料管理器](concepts.md#crypt-materials-manager) (CMM) 可以在加密消息前向提供的加密上下文添加键值对。  
在中 AWS Encryption SDK for C，解密时无需提供加密上下文，因为加密上下文包含在 SDK 返回的加密消息中。但是，在其返回明文消息前，您的解密函数应验证用于解密消息的加密上下文中包含所提供的加密上下文中的所有键值对。  
首先，获取会话中哈希表的只读指针。该哈希表包含用于解密消息的加密上下文。  

```
const struct aws_hash_table *session_enc_ctx = aws_cryptosdk_session_get_enc_ctx_ptr(session);
```
然后，遍历加密时复制的 `my_enc_ctx` 哈希表中的加密上下文。验证用于解密的 `session_enc_ctx` 哈希表包含用于加密的 `my_enc_ctx` 哈希表中的所有键值对。如果缺少任何密钥，或密钥具有不同的值，则停止处理并输出错误消息。  

```
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();
    }
}
```

步骤6：清理会话。  
验证加密上下文后，可以销毁会话，或重用会话。如果需要重新配置会话，请使用 `aws_cryptosdk_session_reset` 方法。  

```
aws_cryptosdk_session_destroy(session);
```

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

fo AWS Encryption SDK r .NET 是一个客户端加密库，适用于使用 C\$1 和其他.NET 编程语言编写应用程序的开发人员。它在 Windows、macOS 和 Linux 上受支持。

**注意**  
 AWS Encryption SDK 适用于.NET 的 4.0.0 版本与《消息规范》 AWS Encryption SDK 有所不同。因此，由 4.0.0 版加密的消息只能通过.NET 版本 4.0.0 或更高版本进行解密。 AWS Encryption SDK 任何其他编程语言都无法对其进行解密。  
for .NET AWS Encryption SDK 的 4.0.1 版根据消息规范写入 AWS Encryption SDK 消息，并且可与其他编程语言实现互操作。默认情况下，版本 4.0.1 可以读取版本 4.0.0 加密的消息。但如果您不想解密由版本 4.0.0 加密的消息，则可以指定 [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) 属性来阻止客户端读取这些消息。有关更多信息，请参阅 aws-encryption-sdk存储库中的 [v4.0.1 版本说明](https://github.com/aws/aws-encryption-sdk/releases/tag/v4.0.1)。 GitHub

f AWS Encryption SDK or .NET 与其他一些编程语言实现的不同之处 AWS Encryption SDK 在于：
+ 不支持[数据密钥缓存](data-key-caching.md)
**注意**  
版本 4。 .NET AWS Encryption SDK 的 *x* 支持[AWS KMS 分层密钥环](use-hierarchical-keyring.md)，这是一种替代的加密材料缓存解决方案。
+ 不支持流数据
+ 来自适用于 .NET 的 AWS Encryption SDK 的[无日志记录或堆栈跟踪](#dot-net-debugging)
+ [需要 适用于 .NET 的 AWS SDK](#dot-net-install)

.N AWS Encryption SDK ET 版包括 2.0 版中引入的所有安全功能。 *x* 及更高版本的其他语言实现 AWS Encryption SDK。但是，如果您使用 for .NET 来解密由 2.0 之前版本加密的数据。 AWS Encryption SDK *x* 版本的另一种语言实现 AWS Encryption SDK，您可能需要调整[承诺政策](concepts.md#commitment-policy)。有关更多信息，请参阅 [如何设置您的承诺策略](migrate-commitment-policy.md#migrate-commitment-step1)。

f AWS Encryption SDK or .NET 是 [Dafny AWS Encryption SDK](https://github.com/dafny-lang/dafny/blob/master/README.md) 中的产物，这是一种正式的验证语言，你可以用它来编写规范、实现规范的代码以及测试规范。结果为在确保功能正确性的框架中实施 AWS Encryption SDK 功能的库。

**了解更多**
+ 有关显示如何在中配置选项（例如指定备用算法套件 AWS Encryption SDK、限制加密数据密钥和使用 AWS KMS 多区域密钥）的示例，请参阅[正在配置 AWS Encryption SDK](configure.md)。
+ 有关使用 for .NET AWS Encryption SDK 进行编程的详细信息，请参阅上的 aws-encryption-sdk存储库[https://github.com/aws/aws-encryption-sdk/tree/mainline/AwsEncryptionSDK/runtimes/net/](https://github.com/aws/aws-encryption-sdk/tree/mainline/AwsEncryptionSDK/runtimes/net/)目录 GitHub。

**Topics**
+ [安装和构建](#dot-net-install)
+ [调试](#dot-net-debugging)
+ [示例](dot-net-examples.md)

## AWS Encryption SDK 为.NET 安装的
<a name="dot-net-install"></a>

.N AWS Encryption SDK ET 版作为[https://www.nuget.org/packages/AWS.Cryptography.EncryptionSDK](https://www.nuget.org/packages/AWS.Cryptography.EncryptionSDK)软件包提供 NuGet。有关安装和构建.NET 版的 AWS Encryption SDK 详细信息，请参阅存储库中的 [README.md](https://github.com/aws/aws-encryption-sdk/tree/mainline/AwsEncryptionSDK/runtimes/net/#readme) 文件。`aws-encryption-sdk-net`

**版本 3.x**  
版本 3。 .NET 版 AWS Encryption SDK 的 *x* 仅在 Windows 上支持.NET 框架 4.5.2 — 4.8。其在所有支持的操作系统中均支持 .NET Core 3.0\$1 和 .NET 5.0 及更高版本。

**版本 4.x**  
版本 4。 .NET 的 * AWS Encryption SDK x* 支持.NET 6.0 和.NET Framework net48 及更高版本。版本 4。 *x* 需要适用于.NET 的 AWS SDK v3。

**版本 5.x**  
版本 5。 .NET 的 * AWS Encryption SDK x* 支持.NET 6.0 和.NET Framework net48 及更高版本。版本 5。 *x* 需要版本 2。 材质提供者库 (MPL) 中的 *x* 和适用于.NET 的 AWS SDK v4。

 适用于 .NET 的 SDK 即使你没有使用 AWS Key Management Service (AWS KMS) 键，for .NET 也需要。 AWS Encryption SDK 它与 NuGet 软件包一起安装。但是，除非您使用的是 AWS KMS 密钥， AWS Encryption SDK 否则.NET 不需要 AWS 凭据或与任何 AWS 服务的交互。 AWS 账户如需有关设置 AWS 账户的帮助，请参阅[使用 wit AWS Encryption SDK h AWS KMS](getting-started.md)。

## AWS Encryption SDK 为.NET 调试
<a name="dot-net-debugging"></a>

fo AWS Encryption SDK r .NET 不生成任何日志。.NET 中的 AWS Encryption SDK 异常会生成异常消息，但不会生成堆栈跟踪。

为了帮助您进行调试，请务必在 适用于 .NET 的 SDK中启用日志记录功能。中的日志和错误消息 适用于 .NET 的 SDK 可以帮助您区分.NET 中出现的 适用于 .NET 的 SDK 错误和.NET 中出现 AWS Encryption SDK 的错误。有关 适用于 .NET 的 SDK 日志记录的帮助，请参阅[AWSLogging](https://docs.aws.amazon.com/sdk-for-net/v4/developer-guide/net-dg-config-other.html#config-setting-awslogging)《*适用于 .NET 的 AWS SDK 开发人员指南》*。（要查看该主题，请展开 **Open to view .NET Framework content** 部分。）

# AWS Encryption SDK 查看.NET 示例
<a name="dot-net-examples"></a>

以下示例显示了您在使用 for .NET AWS Encryption SDK 进行编程时使用的基本编码模式。具体而言，您可以实例化材料提供者库 AWS Encryption SDK 和材料提供者库。然后，在调用每个方法之前，首先实例化定义该方法输入的对象。这与您在 适用于 .NET 的 SDK中使用的编码模式非常相似。

有关显示如何在中配置选项（例如指定备用算法套件 AWS Encryption SDK、限制加密数据密钥和使用 AWS KMS 多区域密钥）的示例，请参阅[正在配置 AWS Encryption SDK](configure.md)。

有关使用 for .NET AWS Encryption SDK 进行编程的更多[示例，请参阅上`aws-encryption-sdk`存储库`aws-encryption-sdk-net`目录中的示例](https://github.com/aws/aws-encryption-sdk/tree/mainline/AwsEncryptionSDK/runtimes/net/Examples) GitHub。

## 加密.NET 中的 AWS Encryption SDK 数据
<a name="dot-net-example-encrypt"></a>

此示例说明了数据加密的基本模式。它使用受一个 AWS KMS 包装密钥保护的数据密钥对一个小文件进行加密。

第 1 步：实例化材料提供者库 AWS Encryption SDK 和材料提供者库。  
首先实例化材料提供者库 AWS Encryption SDK 和材料提供者库。您将使用中的方法 AWS Encryption SDK 来加密和解密数据。您将使用材料提供程序库中的方法创建密钥环，密钥环指定哪些密钥保护您的数据。  
在版本 3 中，实例化材料提供者库 AWS Encryption SDK 和材质提供者库的方式有所不同。 *x* 和 4。 .NET AWS Encryption SDK 的 *x*。两个版本 3 的以下所有步骤都相同。 *x* 和 4。 .NET AWS Encryption SDK 的 *x*。  

```
// 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());
```

步骤 2：为密钥环创建输入对象。  
每个密钥环创建方法均有对应的输入对象类。例如，要为 `CreateAwsKmsKeyring()` 方法创建输入对象，请创建 `CreateAwsKmsKeyringInput` 类的实例。  
尽管此密钥环的输入未指定[生成器密钥](use-kms-keyring.md#kms-keyring-encrypt)，但 `KmsKeyId` 参数指定的单个 KMS 密钥即为生成器密钥。其生成并加密进行数据加密的数据密钥。  
此输入对象需要 AWS KMS 客户端来获取 KMS 密钥。 AWS 区域 要创建 AWS KMS 客户端，请在中实例化该`AmazonKeyManagementServiceClient`类。 适用于 .NET 的 SDK调用不带参数的 `AmazonKeyManagementServiceClient()` 构造函数会创建具有默认值的客户端。  
在 AWS Encryption SDK 用于.NET 加密的密 AWS KMS 钥环中，您可以使用密钥 ID、[密钥 ARN、别名或别名 ARN 来识别](use-kms-keyring.md#kms-keyring-id) KMS 密钥。在用于解密的密 AWS KMS 钥环中，必须使用密钥 ARN 来识别每个 KMS 密钥。如果您计划重复使用加密密钥环进行解密，请将密钥 ARN 标识符用于所有 KMS 密钥。  

```
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
};
```

步骤 3：创建密钥环。  
要创建密钥环，请使用密钥环输入对象调用密钥环方法。此示例使用 `CreateAwsKmsKeyring()` 方法，该方法只需一个 KMS 密钥。  

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

步骤 4：定义加密上下文。  
[加密上下文](concepts.md#encryption-context)是可选的，但强烈建议在中进行加密操作。 AWS Encryption SDK您可以定义一个或多个非机密键值对。  
使用版本 4。 *x* AWS Encryption SDK 对于.NET，您可以使用所需的加密上下文 [CMM 在所有加密请求中要求使用加密上下文](configure.md#config-required-encryption-context-cmm)。

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

步骤 5：创建用于加密的输入对象。  
在调用 `Encrypt()` 方法之前，请创建 `EncryptInput` 类实例。  

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

步骤 6：加密明文。  
使用`Encrypt()`的方法，使用您定义 AWS Encryption SDK 的密钥环对纯文本进行加密。  
`Encrypt() ` 方法返回的 `EncryptOutput` 包含用于获取加密消息 (`Ciphertext`)、加密上下文和算法套件的方法。  

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

步骤 7：获取加密消息。  
for .N AWS Encryption SDK ET 中的`Decrypt()`方法采用`EncryptOutput`实例`Ciphertext`的成员。  
`EncryptOutput` 对象的 `Ciphertext` 成员是[加密消息](concepts.md#message)，其为便携式对象，其中包括加密数据、加密数据密钥和元数据，包括加密上下文。您可以长时间安全存储加密消息，也可以将其提交给 `Decrypt()` 方法以便恢复明文。  

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

## 在 for .NET 中以严格模式解密 AWS Encryption SDK
<a name="dot-net-decrypt-strict"></a>

最佳实践建议您指定用于解密数据的密钥，该选项称为*严格模式*。仅 AWS Encryption SDK 使用您在密钥环中指定的 KMS 密钥来解密密文。解密密钥环中的密钥必须包含至少一个加密数据的密钥。

此示例说明了使用适用于 .NET 的 AWS Encryption SDK 在严格模式下进行解密的基本模式。

第 1 步：实例化 AWS Encryption SDK 和材料提供者库。  

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

步骤 2：为密钥环创建输入对象。  
要为密钥环方法指定参数，请创建输入对象。for .NET 中的 AWS Encryption SDK 每个密钥环方法都有一个对应的输入对象。由于此示例使用 `CreateAwsKmsKeyring()` 方法创建密钥环，因此会为输入实例化 `CreateAwsKmsKeyringInput` 类。  
在解密密钥环中，您必须使用密钥 ARN 标识 KMS 密钥。  

```
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
};
```

步骤 3：创建密钥环。  
要创建解密密钥环，此示例使用 `CreateAwsKmsKeyring()` 方法和密钥环输入对象。  

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

步骤 4：创建用于解密的输入对象。  
要为 `Decrypt()` 方法创建输入对象，请实例化 `DecryptInput` 类。  
`DecryptInput()` 构造函数的 `Ciphertext` 参数需要 `Encrypt()` 方法返回的 `EncryptOutput` 对象 `Ciphertext` 的成员。`Ciphertext` 属性表示[加密消息](concepts.md#message)，其中包括加密数据、加密数据密钥和 AWS Encryption SDK 解密消息所需元数据。  
使用版本 4。 *x* AWS Encryption SDK 对于.NET，您可以使用可选`EncryptionContext`参数在`Decrypt()`方法中指定您的加密上下文。  
使用 `EncryptionContext` 参数验证加密时使用的加密上下文*是否包含*在用于解密加密文字的加密上下文中。如果您使用的是带签名的算法套件（例如默认算法套件），则会将成对 AWS Encryption SDK 添加到加密上下文中，包括数字签名。  

```
var encryptedMessage = encryptOutput.Ciphertext;

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

步骤 5：解密加密文字。  

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

步骤 6：验证加密上下文 – 版本 3.*x*  
版本 3 `Decrypt()` 的方法。 .NET AWS Encryption SDK 的 *x* 不采用加密上下文。其会从加密消息的元数据中获取加密上下文值。但是，在返回或使用明文之前，最佳做法是验证用于解密加密文字的加密上下文是否包含您在加密时提供的加密上下文。  
验证加密时使用的加密上下文*是否包含*在用于解密加密文字的加密上下文中。如果您使用的是带签名的算法套件（例如默认算法套件），则会将成对 AWS Encryption SDK 添加到加密上下文中，包括数字签名。  

```
// 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");
}
```

## 在 for .NET 中使用发现密钥环进行解密 AWS Encryption SDK
<a name="dot-net-decrypt-discovery"></a>

您可以提供不指定任何 KMS 密钥的密钥环， AWS KMS *Discovery 密钥环*，而非指定用于解密的 KMS 密钥。发现 AWS Encryption SDK 密钥环允许使用任何加密数据的 KMS 密钥来解密数据，前提是调用者拥有密钥的解密权限。要获得最佳实践，请添加发现过滤器，将可用于特定分区的 KMS 密钥限制为特定 AWS 账户 分区的密钥。

fo AWS Encryption SDK r .NET 提供了一个基本的发现密钥环，它需要一个 AWS KMS 客户端，还有一个发现多密钥环，需要你指定一个或多个密钥环。 AWS 区域客户端和区域均限制可用于解密加密消息的 KMS 密钥。两个密钥环的输入对象均需要建议添加的发现筛选条件。

以下示例说明了使用 AWS KMS Discovery 密钥环和发现筛选条件解密数据的模式。

第 1 步：实例化材料提供者库 AWS Encryption SDK 和材料提供者库。  

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

步骤 2：为密钥环创建输入对象。  
要为密钥环方法指定参数，请创建输入对象。for .NET 中的 AWS Encryption SDK 每个密钥环方法都有一个对应的输入对象。由于此示例使用 `CreateAwsKmsDiscoveryKeyring()` 方法创建密钥环，因此会为输入实例化 `CreateAwsKmsDiscoveryKeyringInput` 类。  

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

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

步骤 3：创建密钥环。  
要创建解密密钥环，此示例使用 `CreateAwsKmsDiscoveryKeyring()` 方法和密钥环输入对象。  

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

步骤 4：创建用于解密的输入对象。  
要为 `Decrypt()` 方法创建输入对象，请实例化 `DecryptInput` 类。`Ciphertext` 参数的值为 `Encrypt()` 方法返回的 `EncryptOutput` 对象的 `Ciphertext` 成员。  
使用版本 4。 *x* AWS Encryption SDK 对于.NET，您可以使用可选`EncryptionContext`参数在`Decrypt()`方法中指定您的加密上下文。  
使用 `EncryptionContext` 参数验证加密时使用的加密上下文*是否包含*在用于解密加密文字的加密上下文中。如果您使用的是带签名的算法套件（例如默认算法套件），则会将成对 AWS Encryption SDK 添加到加密上下文中，包括数字签名。  

```
var ciphertext = encryptOutput.Ciphertext;

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

步骤 5：验证加密上下文 – 版本 3.*x*  
版本 3 `Decrypt()` 的方法。 .NET AWS Encryption SDK 的 *x* 不开启加密上下文`Decrypt()`。其会从加密消息的元数据中获取加密上下文值。但是，在返回或使用明文之前，最佳做法是验证用于解密加密文字的加密上下文是否包含您在加密时提供的加密上下文。  
验证加密时使用的加密上下文*是否包含*在曾用于解密加密文字的加密上下文中。如果您使用的是带签名的算法套件（例如默认算法套件），则会将成对 AWS Encryption SDK 添加到加密上下文中，包括数字签名。  

```
// 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>

本主题介绍如何安装和使用 fo AWS Encryption SDK r Go。有关使用 for Go AWS Encryption SDK 进行编程的详细信息，请参阅上 aws-encryption-sdk存储库的 [go](https://github.com/aws/aws-encryption-sdk/tree/mainline/releases/go/encryption-sdk/) 目录 GitHub。

f AWS Encryption SDK or Go 与其他一些编程语言实现的不同之处 AWS Encryption SDK 在于：
+ 不支持[数据密钥缓存](data-key-caching.md)。但是，fo AWS Encryption SDK r Go 支持[AWS KMS 分层密钥环](use-hierarchical-keyring.md)，这是一种替代的加密材料缓存解决方案。
+ 不支持流数据

fo AWS Encryption SDK r Go 包含 2.0 版本中引入的所有安全功能。 *x* 及更高版本的其他语言实现 AWS Encryption SDK。但是，如果您使用 for AWS Encryption SDK Go 来解密由 2.0 之前版本加密的数据。 *x* 版本的另一种语言实现 AWS Encryption SDK，您可能需要调整[承诺政策](concepts.md#commitment-policy)。有关更多信息，请参阅 [如何设置您的承诺策略](migrate-commitment-policy.md#migrate-commitment-step1)。

f AWS Encryption SDK or Go 是 AWS Encryption SDK in [Dafny](https://github.com/dafny-lang/dafny/blob/master/README.md) 的产物，这是一种正式的验证语言，你可以用它来编写规范、实现规范的代码以及测试规范。结果为在确保功能正确性的框架中实施 AWS Encryption SDK 功能的库。

**了解更多**
+ 有关显示如何在中配置选项（例如指定备用算法套件 AWS Encryption SDK、限制加密数据密钥和使用 AWS KMS 多区域密钥）的示例，请参阅[正在配置 AWS Encryption SDK](configure.md)。
+ 有关如何配置和使用 for Go AWS Encryption SDK 的示例，请参阅上 aws-encryption-sdk存储库中的 [Go 示例](https://github.com/aws/aws-encryption-sdk/tree/mainline/releases/go/encryption-sdk/examples) GitHub。

**Topics**
+ [

## 先决条件
](#prerequisites-go)
+ [

## 安装
](#go-installation)

## 先决条件
<a name="prerequisites-go"></a>

在安装 fo AWS Encryption SDK r Go 之前，请确保满足以下先决条件。

**支持的 Go 版本**  
Go 需要 AWS Encryption SDK 使用 Go 1.23 或更高版本。  
有关下载和安装 Go 的更多信息，请参阅 [Go 安装](https://go.dev/doc/install)。

## 安装
<a name="go-installation"></a>

安装最新版本的 fo AWS Encryption SDK r Go。有关安装和构建 for Go AWS Encryption SDK 的详细信息，请参阅上存储库 go 目录中的 [README.md。](https://github.com/aws/aws-encryption-sdk/tree/mainline/releases/go/encryption-sdk/README.md) aws-encryption-sdk GitHub

**安装最新版本**
+ 安装 fo AWS Encryption SDK r Go

  ```
  go get github.com/aws/aws-encryption-sdk/releases/go/encryption-sdk@latest
  ```
+ 安装[加密材料提供程序库](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>

本主题介绍了如何安装和使用 AWS Encryption SDK for Java。有关使用编程的详细信息 AWS Encryption SDK for Java，请参阅上的[aws-encryption-sdk-java](https://github.com/aws/aws-encryption-sdk-java/)存储库 GitHub。有关 API 文档，请参阅适用于 AWS Encryption SDK for Java的 [Javadoc](https://aws.github.io/aws-encryption-sdk-java/)。

**Topics**
+ [

## 先决条件
](#java-prerequisites)
+ [

## 安装
](#java-installation)
+ [示例](java-example-code.md)

## 先决条件
<a name="java-prerequisites"></a>

在安装之前 AWS Encryption SDK for Java，请确保满足以下先决条件。

**Java 开发环境**  
您需要使用 Java 8 或更高版本。在 Oracle 网站上，转到 [Java SE 下载](https://www.oracle.com/java/technologies/downloads/)，然后下载并安装 Java SE Development Kit (JDK)。  
如果使用 Oracle JDK，您还必须下载并安装 [Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files](http://www.oracle.com/java/technologies/javase-jce8-downloads.html)。

**Bouncy Castle**  
 AWS Encryption SDK for Java 需要[充气城堡](https://www.bouncycastle.org/download/bouncy-castle-java/)。  
+ AWS Encryption SDK for Java 1.6.1 及更高版本使用 Bouncy Castle 对加密对象进行序列化和反序列化。您可以使用 Bouncy Castle 或 [Bouncy Castle FIPS](https://www.bouncycastle.org/about/bouncy-castle-fips-faq/) 以满足该要求。**有关安装和配置 Bouncy Castle FIPS 的帮助，请参阅 [BC FIPS 文档](https://www.bouncycastle.org/documentation/)，尤其是**用户指南和安全**政策。** PDFs
+ 早期版本 AWS Encryption SDK for Java 使用 Bouncy Castle 的 Java 加密 API。仅非 FIPS Bouncy Castle 满足该要求。
如果你没有 Bouncy Castle，请前往[下载 Java 版 Bouncy Castle](https://bouncycastle.org/download/bouncy-castle-java/) 下载与你的 JDK 对应的提供程序文件。[你也可以使用 [Apache Mav](https://maven.apache.org/) en 获取标准 Bouncy Castle 提供者（[bcprov-ext-jdk15 on](https://mvnrepository.com/artifact/org.bouncycastle/bcprov-ext-jdk15on)）的神器或 Bouncy Castle FIPS 的神器（bc-fips）。](https://mvnrepository.com/artifact/org.bouncycastle/bc-fips)

**适用于 Java 的 AWS SDK**  
版本 3。 *其中 x* AWS Encryption SDK for Java 需要 AWS SDK for Java 2.x，即使你不使用 AWS KMS 钥匙圈。  
版本 2。 *x* 或更早版本 AWS Encryption SDK for Java 不需要 适用于 Java 的 AWS SDK。但是 适用于 Java 的 AWS SDK ，必须使用 [AWS Key Management Service](https://aws.amazon.com/kms/)(AWS KMS) 作为主密钥提供程序。从 2.4.0 AWS Encryption SDK for Java 版本开始，同时 AWS Encryption SDK for Java 支持 1.x 和 2.x 版本的。 适用于 Java 的 AWS SDK AWS Encryption SDK 适用于 Java 的 AWS SDK 1.x 和 2.x 的代码是可互操作的。例如，您可以使用支持 适用于 Java 的 AWS SDK 1.x 的 AWS Encryption SDK 代码加密数据，然后使用支持的代码对其进行解密 AWS SDK for Java 2.x （反之亦然）。2.4.0 AWS Encryption SDK for Java 之前的版本仅支持 适用于 Java 的 AWS SDK 1.x。有关更新版本的信息 AWS Encryption SDK，请参阅[迁移你的 AWS Encryption SDK](migration.md)。  
将 AWS Encryption SDK for Java 代码从 1.x 更新到时 AWS SDK for Java 2.x，请将 适用于 Java 的 AWS SDK 1.x 中对[`AWSKMS`接口](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/kms/package-summary.html)的引用替换为中 适用于 Java 的 AWS SDK 对[`KmsClient`接口](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/kms/package-summary.html)的引用。 AWS SDK for Java 2.x AWS Encryption SDK for Java 不支持该[`KmsAsyncClient`接口](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/kms/KmsAsyncClient.html)。此外，更新代码即可使用 `kmssdkv2` 命名空间中的 AWS KMS相关对象，而不是 `kms` 命名空间。  
要安装，请使用 Apache Maven。 适用于 Java 的 AWS SDK  
+ 要[导入整个 适用于 Java 的 AWS SDK](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/setup-project-maven.html#build-the-entire-sdk-into-your-project)以作为依赖项，请在 `pom.xml` 文件中对其进行声明。
+ 要在 适用于 Java 的 AWS SDK 1.x 中仅为 AWS KMS 模块创建依赖关系，请按照[指定特定模块](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/setup-project-maven.html#modules-dependencies)的说明进行操作，并将设置为。`artifactId` `aws-java-sdk-kms`
+ 要在 适用于 Java 的 AWS SDK 2.x 中仅为 AWS KMS 模块创建依赖关系，请按照[指定特定模块](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/setup-project-maven.html#modules-dependencies)的说明进行操作。将 `groupId` 设置为 `software.amazon.awssdk`，并将 `artifactId` 设置为 `kms`。
有关更多更改，请参阅[《 AWS SDK for Java 2.x 开发者指南》中的 适用于 Java 的 AWS SDK 1.x 和 2.x 有什么区别](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/migration-whats-different.html)。  
《 AWS Encryption SDK 开发人员指南》中的 Java 示例使用 AWS SDK for Java 2.x。

## 安装
<a name="java-installation"></a>

安装最新版本的 AWS Encryption SDK for Java。

**注意**  
[2.0.0 AWS Encryption SDK for Java 之前的所有版本都处于该阶段。end-of-support](https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html#version-life-cycle)  
您可以安全地从 AWS Encryption SDK for Java 版本 2.0.*x* 及更高版本更新为最新版本，无需更改任何代码或数据。但是，版本 2.0.*x* 中引入了[新的安全功能](about-versions.md#version-2)，不向后兼容。要从 1.7.*x* 之前的版本更新到 2.0.*x* 及更高版本，必须先更新到 AWS Encryption SDK最新版本 1.*x*。有关更多信息，请参阅 [迁移你的 AWS Encryption SDK](migration.md)。

您可以通过以下 AWS Encryption SDK for Java 方式安装。

**手动方式**  
要安装 AWS Encryption SDK for Java，请克隆或下载[aws-encryption-sdk-java](https://github.com/aws/aws-encryption-sdk-java/) GitHub存储库。

**使用 Apache Maven**  
可通过 [Apache Maven](https://maven.apache.org/) 获得，依赖关系定义如下。 AWS Encryption SDK for Java   

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

安装完软件开发工具包后，请先查看本指南中的[示例 Java 代码](java-example-code.md)，然后打开 J [avadoc](https://aws.github.io/aws-encryption-sdk-java/)。 GitHub

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

以下示例向您展示了如何使用 AWS Encryption SDK for Java 来加密和解密数据。这些示例说明了如何使用版本 3。 *x* 及更高版本的 AWS Encryption SDK for Java. 版本 3。 其中的 *x* AWS Encryption SDK for Java 需要 AWS SDK for Java 2.x。版本 3。 *其中 x* AWS Encryption SDK for Java 将[主密钥提供程序](concepts.md#master-key-provider)替换为密[钥环](concepts.md#keyring)。有关使用早期版本的示例，请在上[aws-encryption-sdk-java](https://github.com/aws/aws-encryption-sdk-java/)存储库的[版本](https://github.com/aws/aws-encryption-sdk-java/releases)列表中找到您的版本 GitHub。

**Topics**
+ [字符串](#java-example-strings)
+ [字节流](#java-example-streams)
+ [具有多个主密钥提供程序的字节流](#java-example-multiple-providers)

## 加密和解密字符串
<a name="java-example-strings"></a>

以下示例向您展示了如何使用版本 3。 用于加密和解密字符串的 *x*。 AWS Encryption SDK for Java 在使用字符串之前，请将其转换为字节数组。

此示例使用密[AWS KMS 钥环](use-kms-keyring.md)。使用密 AWS KMS 钥环加密时，您可以使用密钥 ID、密钥 ARN、别名或别名 ARN 来识别 KMS 密钥。解密时，必须使用密钥 ARN 来识别 KMS 密钥。

在调用 `encryptData()` 方法时，它返回[加密的消息](concepts.md#message) (`CryptoResult`)，其中包括密文、加密的数据密钥以及加密上下文。在对 `CryptoResult` 对象调用 `getResult` 时，它返回[加密的消息](message-format.md)的 base-64 编码的字符串版本，您可以将其传递给 `decryptData()` 方法。

同样，当您调用时`decryptData()`，它返回的`CryptoResult`对象包含纯文本消息和一个 AWS KMS key ID。在您的应用程序返回纯文本之前，请验证加密消息中的 AWS KMS key ID 和加密上下文是否符合您的期望。

```
// 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);
  }
}
```

## 加密和解密字节流
<a name="java-example-streams"></a>

以下示例说明如何使用 AWS Encryption SDK 来加密和解密字节流。

此示例使用[原始的 AES 密钥环](use-raw-aes-keyring.md)。

加密时，此示例使用 `AwsCrypto.builder() .withEncryptionAlgorithm()` 方法指定不带[数字签名](concepts.md#digital-sigs)的算法套件。解密时，为确保加密文字未签名，此示例使用 `createUnsignedMessageDecryptingStream()` 方法。如果遇到带有数字签名的密文，则该`createUnsignedMessageDecryptingStream()`方法将失败。

如果您使用默认算法套件（包括数字签名）进行加密，请改用 `createDecryptingStream()` 方法，如下一个示例所示。

```
// 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");
    }
}
```

## 使用多密钥环加密和解密字节流
<a name="java-example-multiple-providers"></a>

以下示例向您展示了如何将与[多密钥 AWS Encryption SDK](use-multi-keyring.md)环一起使用。在使用多重密钥环加密数据时，其任意密钥环中的任意包装密钥都可以对数据进行解密。此示例使用[AWS KMS 密钥环](use-kms-keyring.md)和 Ra [w RSA 密钥环作为子密钥环](use-raw-rsa-keyring.md)。

此示例使用包含[数字签名](concepts.md#digital-sigs)的[默认算法套件](supported-algorithms.md)进行加密。直播时，会在完整性检查后但在验证数字签名之前 AWS Encryption SDK 发布纯文本。为了避免在签名验证之前使用明文，此示例会缓冲明文，并且仅在解密和验证完成后才将其写入磁盘。

```
// 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>

旨在 AWS Encryption SDK for JavaScript 为在 Node.js 中编写 Web 浏览器应用程序 JavaScript 或使用编写 Web 服务器应用程序的开发人员提供客户端加密库。

与的所有实现一样 AWS Encryption SDK， AWS Encryption SDK for JavaScript 提供了高级数据保护功能。这些功能包括[信封加密](concepts.md#envelope-encryption)、其他经过身份验证的数据 (AAD) 以及安全、经过身份验证且对称的密钥[算法套件](concepts.md#crypto-algorithm)，如具有密钥派生和签名的 256 位 AES-GCM。

的所有特定于语言的实现 AWS Encryption SDK 都被设计为可互操作，但要遵守语言的限制。有关语言限制的详细信息 JavaScript，请参阅[的兼容性 AWS Encryption SDK for JavaScript](javascript-compatibility.md)。

**了解更多**
+ 有关使用编程的详细信息 AWS Encryption SDK for JavaScript，请参阅上的[aws-encryption-sdk-javascript](https://github.com/aws/aws-encryption-sdk-javascript/)存储库 GitHub。
+ 有关编程示例，请参阅[AWS Encryption SDK for JavaScript 例子](js-examples.md)以及存储[库中的示例浏览器](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/example-browser)和[示例节点](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/example-node)模块。[aws-encryption-sdk-javascript](https://github.com/aws/aws-encryption-sdk-javascript/)
+  有关使用在 Web 应用程序中加密数据的真实示例，请参阅 AWS 安全博客[中的如何使用 AWS Encryption SDK for JavaScript 和 Node.js 在浏览器中启用加密](https://aws.amazon.com/blogs/security/how-to-enable-encryption-browser-aws-encryption-sdk-javascript-node-js/)。 AWS Encryption SDK for JavaScript 

**Topics**
+ [兼容性](javascript-compatibility.md)
+ [安装](javascript-installation.md)
+ [模块](javascript-modules.md)
+ [示例](js-examples.md)

# 的兼容性 AWS Encryption SDK for JavaScript
<a name="javascript-compatibility"></a>

 AWS Encryption SDK for JavaScript 旨在与的其他语言实现实现互操作。 AWS Encryption SDK在大多数情况下，您可以使用加密数据，也可以使用任何其他语言实现（包括[AWS Encryption SDK 命令行界](crypto-cli.md)面）对其进行解密。 AWS Encryption SDK for JavaScript 而且，您可以使用 AWS Encryption SDK for JavaScript 来解密由的其他语言实现生成的[加密消息](concepts.md#message)。 AWS Encryption SDK

但是，在使用时 AWS Encryption SDK for JavaScript，您需要注意 JavaScript 语言实现和 Web 浏览器中的一些兼容性问题。

此外，在使用不同的语言实施时，请务必配置兼容的主密钥提供程序、主密钥和密钥环。有关更多信息，请参阅 [密钥环兼容性](choose-keyring.md#keyring-compatibility)。

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

的 JavaScript 实现与其他语言实现的 AWS Encryption SDK 不同之处在于：
+ 的加密操作 AWS Encryption SDK for JavaScript 不会返回非成帧的密文。但是， AWS Encryption SDK for JavaScript 将解密其他语言实现返回的带框和非成帧的密文。 AWS Encryption SDK
+ 从 Node.js 12.9.0 版开始，Node.js 支持以下 RSA 密钥包装选项：
  + OAEP 带有 SHA1、 SHA256、 SHA384、或 SHA512
  + OAEP 有 SHA1 和 MGF1 带有 SHA1
  + PKCS1v15
+ 在 12.9.0 版之前，Node.js 仅支持以下 RSA 密钥包装选项：
  + OAEP 有 SHA1 和 MGF1 带有 SHA1
  + PKCS1v15

## 浏览器兼容性
<a name="javascript-browser-compatibility"></a>

某些 Web 浏览器不支持 AWS Encryption SDK for JavaScript 所需的基本加密操作。您可以通过为浏览器实现的 WebCrypto API 配置备用来弥补一些缺失的操作。

**Web 浏览器限制**

以下限制是所有 Web 浏览器通用的：
+  WebCrypto API 不支持 PKCS1v15 密钥封装。
+ 浏览器不支持 192 位密钥。

**所需的加密操作**

 AWS Encryption SDK for JavaScript 需要在 Web 浏览器中执行以下操作。如果浏览器不支持这些操作，则它与 AWS Encryption SDK for JavaScript不兼容。
+ 浏览器必须包含 `crypto.getRandomValues()`，这是一种生成加密随机值的方法。有关支持的 Web 浏览器版本的信息`crypto.getRandomValues()`，请参阅[我能否使用加密货币。 getRandomValues()？](https://caniuse.com/#feat=getrandomvalues) 。

**所需的回退**

 AWS Encryption SDK for JavaScript 需要在 Web 浏览器中使用以下库和操作。如果您支持的 Web 浏览器不满足这些要求，您必须配置回退。否则，尝试在浏览器中 AWS Encryption SDK for JavaScript 使用将失败。
+ 该 WebCrypto API在Web应用程序中执行基本的加密操作，但并非适用于所有浏览器。有关支持 Web 加密的 Web 浏览器版本的信息，请参阅[我是否可以使用 Web 加密？](https://caniuse.com/#feat=cryptography)。
+ 现代版本的 Safari 网络浏览器不支持 AES-GCM 零字节加密，这是必需的。 AWS Encryption SDK 如果浏览器实现了 WebCrypto API，但无法使用 AES-GCM 加密零字节，则仅 AWS Encryption SDK for JavaScript 使用备用库进行零字节加密。它使用 WebCrypto API 进行所有其他操作。

要为这两种限制配置回退，请将以下语句添加到代码中。在 [configureFallback](https://github.com/aws/aws-encryption-sdk-javascript/blob/master/modules/web-crypto-backend/src/backend-factory.ts#L78) 函数中，指定一个支持缺少的功能的库。以下示例使用 Microsoft JavaScript Research 密码学库 (`msrcrypto`)，但你可以将其替换为兼容的库。有关完整的示例，请参阅 [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)
```

# 正在安装 AWS Encryption SDK for JavaScript
<a name="javascript-installation"></a>

 AWS Encryption SDK for JavaScript 由一系列相互依存的模块组成。一些模块只是设计为一起工作的模块的集合。一些模块设计为单独工作。一些模块是所有实施所必需的；而一些其他模块仅在特殊情况下是必需的。有关 for 中模块的信息 JavaScript， AWS Encryption SDK 请参阅，[中的模块 AWS Encryption SDK for JavaScript](javascript-modules.md)以及[aws-encryption-sdk-javascript](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules)存储库中每个模块中的`README.md`文件 GitHub。

**注意**  
[2.0.0 AWS Encryption SDK for JavaScript 之前的所有版本都处于该阶段。end-of-support](https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html#version-life-cycle)  
您可以安全地从 AWS Encryption SDK for JavaScript 版本 2.0.*x* 及更高版本更新为最新版本，无需更改任何代码或数据。但是，版本 2.0.*x* 中引入了[新的安全功能](about-versions.md#version-2)，不向后兼容。要从 1.7.*x* 之前的版本更新到 2.0.*x* 及更高版本，必须先更新到 AWS Encryption SDK for JavaScript最新版本 1.*x*。有关更多信息，请参阅 [迁移你的 AWS Encryption SDK](migration.md)。

要安装这些模块，请使用 [npm package manager](https://www.npmjs.com/get-npm)。

例如，要安装包含在 `client-node` Node.js AWS Encryption SDK for JavaScript 中使用编程所需的所有模块的模块，请使用以下命令。

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

要安装该`client-browser`模块（包括需要在浏览器 AWS Encryption SDK for JavaScript 中使用编程的所有模块），请使用以下命令。

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

有关如何使用的工作示例 AWS Encryption SDK for JavaScript，请参阅[aws-encryption-sdk-javascript](https://github.com/aws/aws-encryption-sdk-javascript/)存储库中的`example-node`和`example-browser`模块中的示例 GitHub。

# 中的模块 AWS Encryption SDK for JavaScript
<a name="javascript-modules"></a>

中的模块可以 AWS Encryption SDK for JavaScript 轻松安装项目所需的代码。

## JavaScript Node.js 的模块
<a name="jsn-modules-node"></a>

[client-node](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/client-node)  
包括在 Node.js 中使用编程所需的所有模块。 AWS Encryption SDK for JavaScript 

[caching-materials-manager-node](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/caching-materials-manager-node)  
在 Node.js 中导出支持[数据密钥缓存](data-key-caching.md)功能 AWS Encryption SDK for JavaScript 的函数。

[decrypt-node](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/decrypt-node)  
导出解密和验证表示数据和数据流的加密消息的函数。包含在 `client-node` 模块中。

[encrypt-node](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/encrypt-node)  
导出对不同类型的数据进行加密和签名的函数。包含在 `client-node` 模块中。

[example-node](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/example-node)  
 AWS Encryption SDK for JavaScript 在 Node.js 中导出使用编程的工作示例。包括不同类型的密钥环和不同类型的数据的示例。

[hkdf-node](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/hkdf-node)  
导出[基于 HMAC 的密钥派生函数](https://en.wikipedia.org/wiki/HKDF) (HKDF)，Node.js AWS Encryption SDK for JavaScript 中的在特定算法套件中使用该函数。浏览器 AWS Encryption SDK for JavaScript 中使用 WebCrypto API 中的原生 HKDF 函数。

[integration-node](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/integration-node)  
定义测试，以验证 Node.js AWS Encryption SDK for JavaScript 中的是否与的其他语言实现兼容 AWS Encryption SDK。

[kms-keyring-node](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/kms-keyring-node)  
在 Node.js 中导出支持 AWS KMS 密钥环的函数。

[raw-aes-keyring-node](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/raw-aes-keyring-node)  
导出在 Node.js 中支持[原始 AES 密钥环](use-raw-aes-keyring.md)的函数。

[raw-rsa-keyring-node](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/raw-rsa-keyring-node)  
导出在 Node.js 中支持[原始 RSA 密钥环](use-raw-rsa-keyring.md)的函数。

## JavaScript 浏览器模块
<a name="jsn-modules-browser"></a>

[client-browser](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/client-browser)  
包括你需要在浏览器 AWS Encryption SDK for JavaScript 中使用编程的所有模块。

[caching-materials-manager-browser](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/caching-materials-manager-browser)  
在浏览器中导出支持[数据密钥缓存](data-key-caching.md)功能 JavaScript 的函数。

[decrypt-browser](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/decrypt-browser)  
导出解密和验证表示数据和数据流的加密消息的函数。

[encrypt-browser](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/encrypt-browser)  
导出对不同类型的数据进行加密和签名的函数。

[example-browser](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/example-browser)  
在浏览器 AWS Encryption SDK for JavaScript 中使用编程的工作示例。包括不同类型的密钥环和不同类型的数据的示例。

[integration-browser](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/integration-browser)  
定义用于验证浏览器中的 AWS Encryption SDK for Java脚本是否与的其他语言实现兼容的测试 AWS Encryption SDK。

[kms-keyring-browser](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/kms-keyring-browser)  
导出在浏览器中支持 [AWS KMS 密钥环](use-kms-keyring.md)的函数。

[raw-aes-keyring-browser](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/raw-aes-keyring-browser)  
导出在浏览器中支持[原始 AES 密钥环](use-raw-aes-keyring.md)的函数。

[raw-rsa-keyring-browser](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/raw-rsa-keyring-browser)  
导出在浏览器中支持[原始 RSA 密钥环](use-raw-rsa-keyring.md)的函数。

## 适用于所有实施的模块
<a name="jsn-modules-all"></a>

[cache-material](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/cache-material)  
支持[数据密钥缓存](data-key-caching.md)功能。提供代码以组装与每个数据密钥一起缓存的加密材料。

[kms-keyring](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/kms-keyring)  
导出支持 [KMS 密钥环](use-kms-keyring.md)的函数。

[material-management](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/material-management)  
实施[加密材料管理器](concepts.md#crypt-materials-manager) (CMM)。

[raw-keyring](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/raw-keyring)  
导出原始 AES 和 RSA 密钥环所需的函数。

[serialize](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/serialize)  
导出该开发工具包用于序列化其输出的函数。

[web-crypto-backend](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/web-crypto-backend)  
在浏览器中导出使用该 WebCrypto API AWS Encryption SDK for JavaScript 的函数。

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

以下示例演示了如何使用 AWS Encryption SDK for JavaScript 加密和解密数据。

你可以在上的 e [xample-node 和 example-](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/example-node) [browser 模块中找到更多使用示例](https://github.com/aws/aws-encryption-sdk-javascript/tree/master/modules/example-browser)。 AWS Encryption SDK for JavaScript [aws-encryption-sdk-javascript](https://github.com/aws/aws-encryption-sdk-javascript/) GitHub在安装 `client-browser` 或 `client-node` 模块时，不会安装这些示例模块。

请**参阅完整的代码示例**：节点：[kms\$1simple.ts](https://github.com/aws/aws-encryption-sdk-javascript/blob/master/modules/example-node/src/kms_simple.ts)，浏览器：[kms\$1simple.ts](https://github.com/aws/aws-encryption-sdk-javascript/blob/master/modules/example-browser/src/kms_simple.ts)

**Topics**
+ [

## 使用密钥环加密 AWS KMS 数据
](#javascript-example-encrypt)
+ [

## 使用密钥环解密数据 AWS KMS
](#javascript-example-decrypt)

## 使用密钥环加密 AWS KMS 数据
<a name="javascript-example-encrypt"></a>

以下示例说明如何使用 AWS Encryption SDK for JavaScript 来加密和解密短字符串或字节数组。

此示例以[AWS KMS 密钥环](use-kms-keyring.md)为特色，这是一种使用生成和加密数据密钥 AWS KMS key 的密钥环。有关创建的帮助 AWS KMS key，请参阅《*AWS Key Management Service 开发者指南》*中的[创建密钥](https://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html)。如需帮助识别 AWS KMS 钥匙圈 AWS KMS keys 中的内容，请参阅 [在 AWS KMS 钥匙圈 AWS KMS keys 中识别](use-kms-keyring.md#kms-keyring-id)

步骤 1：设置承诺政策。  
从 1.7 版本开始。 *x* 中 AWS Encryption SDK for JavaScript，您可以在调用实例化客户端的新`buildClient`函数时设置承诺策略。 AWS Encryption SDK `buildClient` 函数需要表示承诺策略的枚举值。进行加密和解密时，该函数会返回强制执行您的承诺策略的已更新 `encrypt` 和 `decrypt` 函数。  
以下示例使用`buildClient`函数来指定[默认的承诺策略](migrate-commitment-policy.md)`REQUIRE_ENCRYPT_REQUIRE_DECRYPT`。您也可以使用`buildClient`来限制加密消息中加密数据密钥的数量。有关更多信息，请参阅 [限制加密数据密钥](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
)
```

步骤 2：构造密钥环。  
创建用于加密的 AWS KMS 密钥环。  
使用密 AWS KMS 钥环加密时，必须指定*生成器密钥*，即用于生成纯文本数据密钥并对其进行加密的生成器密钥。 AWS KMS key 您还可以指定零个或更多*附加密钥*，以加密相同的明文数据密钥。密钥环返回密钥环中每个 AWS KMS key 密钥的纯文本数据密钥和该数据密钥的一个加密副本，包括生成器密钥。要解密数据，您需要解密任一加密数据密钥。  
要在中 AWS KMS keys 为加密密钥环指定 AWS Encryption SDK for JavaScript，您可以使用[任何支持的 AWS KMS 密钥标识符](use-kms-keyring.md#kms-keyring-id)。该示例使用一个生成器密钥（由其[别名 ARN](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id-alias-ARN) 标识）和一个附加密钥（由[密钥 ARN](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id-key-ARN) 标识）。  
如果您打算重复使用密 AWS KMS 钥环进行解密，则必须使用密钥 ARNs 来识别密钥环 AWS KMS keys 中的密钥。
在运行此代码之前，请将示例标 AWS KMS key 识符替换为有效的标识符。您必须具有在密钥环中[使用 AWS KMS keys所需的权限](use-kms-keyring.md#kms-keyring-permissions)。  
首先，向浏览器提供您的凭证。这些 AWS Encryption SDK for JavaScript 示例使用 [webpack。 DefinePlugin](https://webpack.js.org/plugins/define-plugin/)，它会将凭证常量替换为您的实际证书。但是，您可以使用任何方法以提供凭证。然后，使用凭据创建 AWS KMS 客户端。  

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

const clientProvider = getClient(KMS, {
  credentials: {
    accessKeyId,
    secretAccessKey,
    sessionToken
  }
})
```
接下来， AWS KMS keys 为生成器密钥和其他密钥指定。然后，使用 AWS KMS 客户端和创建 AWS KMS 密钥环。 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 })
```

步骤 3：设置加密上下文。  
[加密上下文](concepts.md#encryption-context)是任意的非机密其他经过身份验证的数据。当您提供有关加密的加密上下文时，会 AWS Encryption SDK 以加密方式将加密上下文绑定到密文，因此解密数据需要相同的加密上下文。使用加密上下文是可选的，但作为一项最佳实践，建议您提供加密上下文。  
创建一个包含加密上下文对的简单对象。每对中的键和值必须是一个字符串。  

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

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

步骤 4：加密数据。  
要加密明文数据，请调用 `encrypt` 函数。传入 AWS KMS 密钥环、纯文本数据和加密上下文。  
`encrypt` 函数返回[加密的消息](concepts.md#message) (`result`)，其中包含加密的数据、加密的数据密钥和重要元数据，包括加密上下文和签名。  
您可以对任何支持的编程语言使用来[解密此加密消息](#javascript-example-decrypt)。 AWS Encryption SDK   

```
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 })
```

## 使用密钥环解密数据 AWS KMS
<a name="javascript-example-decrypt"></a>

您可以使用 AWS Encryption SDK for JavaScript 来解密加密的邮件并恢复原始数据。

在该示例中，我们解密在[使用密钥环加密 AWS KMS 数据](#javascript-example-encrypt)示例中加密的数据。

步骤 1：设置承诺政策。  
从 1.7 版本开始。 *x* 中 AWS Encryption SDK for JavaScript，您可以在调用实例化客户端的新`buildClient`函数时设置承诺策略。 AWS Encryption SDK `buildClient` 函数需要表示承诺策略的枚举值。进行加密和解密时，该函数会返回强制执行您的承诺策略的已更新 `encrypt` 和 `decrypt` 函数。  
以下示例使用`buildClient`函数来指定[默认的承诺策略](migrate-commitment-policy.md)`REQUIRE_ENCRYPT_REQUIRE_DECRYPT`。您也可以使用`buildClient`来限制加密消息中加密数据密钥的数量。有关更多信息，请参阅 [限制加密数据密钥](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
)
```

步骤 2：构造密钥环。  
要解密数据，请传入 `encrypt` 函数返回的[加密消息](concepts.md#message) (`result`)。加密的消息包括加密的数据、加密的数据密钥和重要元数据，包括加密上下文和签名。  
在解密时，您还必须指定一个 [AWS KMS 密钥环](use-kms-keyring.md)。您可以使用用于加密数据的相同密钥环，或者使用不同的密钥环。要成功，解密密钥环 AWS KMS key 中必须至少有一个能够解密加密消息中的一个加密数据密钥。由于没有生成任何数据密钥，您不需要在解密密钥环中指定生成器密钥。如果这样做，将按相同的方式处理生成器密钥和附加密钥。  
[要在中 AWS KMS key 为解密密钥环指定一个 AWS Encryption SDK for JavaScript，必须使用密钥 ARN。](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id-key-ARN)否则 AWS KMS key ，将无法识别。如需帮助识别 AWS KMS 钥匙圈 AWS KMS keys 中的内容，请参阅 [在 AWS KMS 钥匙圈 AWS KMS keys 中识别](use-kms-keyring.md#kms-keyring-id)  
如果您使用相同的密钥环进行加密和解密，请使用密钥 ARNs 来识别密钥环中的 AWS KMS keys 密钥。
在此示例中，我们创建了一个仅包含加密密钥环 AWS KMS keys 中的一个的密钥环。在运行该代码之前，请将示例密钥 ARN 替换为有效 ARN。您必须具有 AWS KMS key的 `kms:Decrypt` 权限。  
首先，向浏览器提供您的凭证。这些 AWS Encryption SDK for JavaScript 示例使用 [webpack。 DefinePlugin](https://webpack.js.org/plugins/define-plugin/)，它会将凭证常量替换为您的实际证书。但是，您可以使用任何方法以提供凭证。然后，使用凭据创建 AWS KMS 客户端。  

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

const clientProvider = getClient(KMS, {
  credentials: {
    accessKeyId,
    secretAccessKey,
    sessionToken
  }
})
```
接下来，使用 AWS KMS 客户端创建 AWS KMS 密钥环。此示例仅使用加密密钥环 AWS KMS keys 中的一个。  

```
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 })
```

步骤 3：解密数据。  
接下来，调用 `decrypt` 函数。传入您刚刚创建的解密密钥环 (`keyring`) 和 `encrypt` 函数返回的[加密消息](concepts.md#message) (`result`)。 AWS Encryption SDK 使用密钥环解密其中一个加密的数据密钥。然后，它使用明文数据密钥以解密数据。  
如果调用成功，则 `plaintext` 字段包含明文（已解密）数据。`messageHeader` 字段包含有关解密过程的元数据，包括用于解密数据的加密上下文。  

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

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

步骤 4：验证加密上下文。  
用于解密数据的[加密上下文](concepts.md#encryption-context)包含在 `decrypt` 函数返回的消息标头 (`messageHeader`) 中。在应用程序返回明文数据之前，请验证在解密时使用的加密上下文中是否包含在加密时提供的加密上下文。如果不匹配，则可能表明数据被篡改，或者您没有解密正确的密文。  
在验证加密上下文时，不需要完全匹配。在将加密算法与签名一起使用时，[加密材料管理器](concepts.md#crypt-materials-manager) (CMM) 在加密消息之前将公有签名密钥添加到加密上下文中。但是，您提交的所有加密上下文对应包含在返回的加密上下文中。  
首先，从消息标头中获取加密上下文。然后，验证原始加密上下文 (`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')
})
```
如果加密上下文检查成功，您可以返回明文数据。

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

本主题介绍了如何安装和使用 AWS Encryption SDK for Python。有关使用编程的详细信息 AWS Encryption SDK for Python，请参阅上的[aws-encryption-sdk-python](https://github.com/aws/aws-encryption-sdk-python/)存储库 GitHub。有关 API 文档，请参阅[阅读文档](https://aws-encryption-sdk-python.readthedocs.io/en/latest/)。

**Topics**
+ [

## 先决条件
](#python-prerequisites)
+ [

## 安装
](#python-installation)
+ [示例](python-example-code.md)

## 先决条件
<a name="python-prerequisites"></a>

在安装之前 AWS Encryption SDK for Python，请确保满足以下先决条件。

**支持的 Python 版本**  
3.2.0 及更高版本需要 Python 3.8 或更高 AWS Encryption SDK for Python 版本。  
[AWS 加密材料提供程序库](https://github.com/aws/aws-cryptographic-material-providers-library) (MPL) 是版本 4 中 AWS Encryption SDK for Python 引入的可选依赖项。 *x*。如果你打算安装 MPL，则必须使用 Python 3.11 或更高版本。
的早期版本 AWS Encryption SDK 支持 Python 2.7 和 Python 3.4 及更高版本，但我们建议您使用最新版本的 AWS Encryption SDK。  
要下载 Python，请参阅 [Python 下载](https://www.python.org/downloads/)。

**适用于 Python 的 pip 安装工具**  
`pip` 包含在 Python 3.6 及更高版本中，但您可能需要对其进行升级。有关升级或安装 `pip` 的更多信息，请参阅 `pip` 文档中的 [Installation](https://pip.pypa.io/en/latest/installation/)。

## 安装
<a name="python-installation"></a>

安装最新版本的 AWS Encryption SDK for Python。

**注意**  
[3.0.0 AWS Encryption SDK for Python 之前的所有版本都处于该阶段。end-of-support](https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html#version-life-cycle)  
您可以安全地从 AWS Encryption SDK 版本 2.0.*x* 及更高版本更新为最新版本，无需更改任何代码或数据。但是，版本 2.0.*x* 中引入了[新的安全功能](about-versions.md#version-2)，不向后兼容。要从 1.7.*x* 之前的版本更新到 2.0.*x* 及更高版本，必须先更新到 AWS Encryption SDK最新版本 1.*x*。有关更多信息，请参阅 [迁移你的 AWS Encryption SDK](migration.md)。

`pip`用于安装 AWS Encryption SDK for Python，如以下示例所示。

**安装最新版本**  

```
pip install "aws-encryption-sdk[MPL]"
```
后`[MPL]`缀安装[AWS 加密材料提供程序库](https://github.com/aws/aws-cryptographic-material-providers-library) (MPL)。MPL 包含用于加密和解密数据的结构。MPL 是版本 4 中 AWS Encryption SDK for Python 引入的可选依赖项。 *x*。我们强烈建议安装 MPL。但是，如果您不打算使用 MPL，则可以省略后`[MPL]`缀。

有关使用 pip 安装和升级程序包的更详细信息，请参阅[安装程序包](https://packaging.python.org/tutorials/installing-packages/)。

 AWS Encryption SDK for Python 需要所有平台上的[密码学库](https://cryptography.io/en/latest/)（pyca/密码学）。`pip` 所有版本均会在 Windows 上自动安装和构建 `cryptography` 库。 `pip` 8.1 及更高版本会自动在 Linux 上安装和构建 `cryptography`。如果使用 `pip` 早期版本，并且 Linux 环境没有构建 `cryptography` 库所需的工具，您需要安装这些工具。有关更多信息，请参阅[在 Linux 上构建加密](https://cryptography.io/en/latest/installation.html#building-cryptography-on-linux)。

该版本的1.10.0和2.5.0版本将[密码学](https://cryptography.io/en/latest/)依赖关系 AWS Encryption SDK for Python 固定在2.5.0和3.3.2之间。其他版本则 AWS Encryption SDK for Python 安装最新版本的密码学。如果您需要比 3.3.2 更高的密码系统版本，我们建议您使用 AWS Encryption SDK for Python的最新主要版本。

有关的最新开发版本 AWS Encryption SDK for Python，请访问中的[aws-encryption-sdk-python](https://github.com/aws/aws-encryption-sdk-python/)存储库 GitHub。

安装完成后 AWS Encryption SDK for Python，请先查看本指南中的 [Python 示例代码](python-example-code.md)。

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

以下示例向您展示了如何使用 AWS Encryption SDK for Python 来加密和解密数据。

本节中的示例说明如何使用版本 4。 其中的 *x* AWS Encryption SDK for Python 具有可选的[加密材料提供程序库](https://github.com/aws/aws-cryptographic-material-providers-library)依赖项 (`aws-cryptographic-material-providers`)。要查看使用早期版本的示例，或者不使用材料提供者库 (MPL) 的安装，请在[aws-encryption-sdk-python](https://github.com/aws/aws-encryption-sdk-python/)存储库的[版本](https://github.com/aws/aws-encryption-sdk-python/releases)列表中找到您的版本。 GitHub

当你使用版本 4 时。 *x* 在 AWS Encryption SDK for Python MPL 中，它使用[密钥环](choose-keyring.md)来执行[信封](concepts.md#envelope-encryption)加密。 AWS Encryption SDK 提供的密钥环与您在先前版本中使用的主密钥提供程序兼容。有关更多信息，请参阅 [密钥环兼容性](choose-keyring.md#keyring-compatibility)。有关从主密钥提供程序迁移到密钥环的示例，请参阅`aws-encryption-sdk-python`存储库中的[迁移示例](https://github.com/aws/aws-encryption-sdk-python/tree/master/examples/src/migration)： GitHub

**Topics**
+ [字符串](#python-example-strings)
+ [字节流](#python-example-streams)

## 加密和解密字符串
<a name="python-example-strings"></a>

以下示例说明如何使用 AWS Encryption SDK 来加密和解密字符串。此示例使用带有对称加密 KMS [AWS KMS 密钥的密钥环](use-kms-keyring.md)。

此示例使用[默认承诺策略](migrate-commitment-policy.md)实例化 AWS Encryption SDK 客户端。`REQUIRE_ENCRYPT_REQUIRE_DECRYPT`有关更多信息，请参阅 [设置您的承诺策略](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"
```

## 加密和解密字节流
<a name="python-example-streams"></a>

以下示例说明如何使用 AWS Encryption SDK 来加密和解密字节流。此示例使用[原始的 AES 密钥环](use-raw-aes-keyring.md)。

此示例使用[默认承诺策略](migrate-commitment-policy.md)实例化 AWS Encryption SDK 客户端。`REQUIRE_ENCRYPT_REQUIRE_DECRYPT`有关更多信息，请参阅 [设置您的承诺策略](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 对于 Rust
<a name="rust"></a>

本主题介绍如何安装和使用 for AWS Encryption SDK Rust。有关使用 for Rust AWS Encryption SDK 进行编程的详细信息，请参阅上 aws-encryption-sdk存储库的 [Rust](https://github.com/aws/aws-encryption-sdk-dafny/tree/mainline/AwsEncryptionSDK/runtimes/rust/) 目录 GitHub。

f AWS Encryption SDK or Rust 与其他一些编程语言实现的不同之处 AWS Encryption SDK 在于：
+ 不支持[数据密钥缓存](data-key-caching.md)。但是，for AWS Encryption SDK Rust 支持[AWS KMS 分层密钥环](use-hierarchical-keyring.md)，这是一种替代的加密材料缓存解决方案。
+ 不支持流数据

f AWS Encryption SDK or Rust 包含 2.0 版本中引入的所有安全功能。 *x* 及更高版本的其他语言实现 AWS Encryption SDK。但是，如果你使用 for Rust 来解密由 2.0 之前版本加密的数据。 AWS Encryption SDK *x* 版本的另一种语言实现 AWS Encryption SDK，您可能需要调整[承诺政策](concepts.md#commitment-policy)。有关更多信息，请参阅 [如何设置您的承诺策略](migrate-commitment-policy.md#migrate-commitment-step1)。

f AWS Encryption SDK or Rust 是 AWS Encryption SDK in [Dafny](https://github.com/dafny-lang/dafny/blob/master/README.md) 的产物，这是一种正式的验证语言，你可以用它来编写规范、实现规范的代码以及测试规范。结果为在确保功能正确性的框架中实施 AWS Encryption SDK 功能的库。

**了解更多**
+ 有关显示如何在中配置选项（例如指定备用算法套件 AWS Encryption SDK、限制加密数据密钥和使用 AWS KMS 多区域密钥）的示例，请参阅[正在配置 AWS Encryption SDK](configure.md)。
+ 有关如何配置和使用 for Rust AWS Encryption SDK 的示例，请参阅上 aws-encryption-sdk存储库中的 [Rust 示例](https://github.com/aws/aws-encryption-sdk-dafny/tree/mainline/AwsEncryptionSDK/runtimes/rust/examples) GitHub。

**Topics**
+ [

## 先决条件
](#prerequisites-rust)
+ [

## 安装
](#rust-installation)
+ [示例](rust-examples.md)

## 先决条件
<a name="prerequisites-rust"></a>

在安装 f AWS Encryption SDK or Rust 之前，请确保满足以下先决条件。

**安装 Rust 和 Cargo**  
使用 [r](https://rustup.rs/) ustup 安装当前稳定版本的 [Rust](https://www.rust-lang.org/)。  
有关下载和安装 rustup 的更多信息，请参阅《货运手册》中的[安装程序](https://doc.rust-lang.org/cargo/getting-started/installation.html)。

## 安装
<a name="rust-installation"></a>

f AWS Encryption SDK or Rust 在 [https://crates.io/crates/aws-esdk](https://crates.io/crates/aws-esdk)Crates.io 上可以作为箱子使用。有关安装和构建 Rust 版 AWS Encryption SDK 的详细信息，请参阅存储库中的 [README.md。](https://github.com/aws/aws-encryption-sdk/tree/mainline) aws-encryption-sdk GitHub

你可以通过以下方式安装 AWS Encryption SDK 适用于 Rust 的。

**手动方式**  
要安装 Rust 版，请克隆或下载[aws-encryption-sdk](https://github.com/aws/aws-encryption-sdk/tree/mainline) GitHub 存储库。 AWS Encryption SDK 

**使用 Crates.io**  
在您的项目目录中运行以下 Cargo 命令：  

```
cargo add aws-esdk
```
或者在你的 Cargo.toml 中添加以下一行：  

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

# AWS Encryption SDK 对于 Rust 的示例代码
<a name="rust-examples"></a>

以下示例显示了使用 for Rust AWS Encryption SDK 进行编程时使用的基本编码模式。具体而言，您可以实例化材料提供者库 AWS Encryption SDK 和材料提供者库。然后，在调用每个方法之前，先实例化定义该方法输入的对象。

有关展示如何在中配置选项（例如指定备用算法套件和限制加密数据密钥）的示例，请参阅 aws-encryption-sdk存储库中的 [Rust 示例](https://github.com/aws/aws-encryption-sdk-dafny/tree/mainline/AwsEncryptionSDK/runtimes/rust/examples/) GitHub。 AWS Encryption SDK

## 在 for Rust 中加密和解密数据 AWS Encryption SDK
<a name="rust-example-encrypt"></a>

此示例显示了加密和解密数据的基本模式。它使用受一个 AWS KMS 包装密钥保护的数据密钥对一个小文件进行加密。

**步骤 1：实例化. AWS Encryption SDK**  
您将使用中的方法 AWS Encryption SDK 来加密和解密数据。  

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

**步骤 2：创建 AWS KMS 客户端。**  

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

**可选：创建您的加密上下文。**  

```
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()),
]);
```

**第 3 步：实例化材料提供者库。**  
您将使用材料提供程序库中的方法创建密钥环，密钥环指定哪些密钥保护您的数据。  

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

**步骤 4：创建 AWS KMS 密钥环。**  
要创建密钥环，请使用密钥环输入对象调用密钥环方法。此示例使用`create_aws_kms_keyring()`方法并指定一个 KMS 密钥。  

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

**第 5 步：加密明文。**  

```
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");
```

**第 6 步：使用与加密时相同的密钥环解密您的加密数据。**  

```
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 命令行界面
<a name="crypto-cli"></a>

 AWS Encryption SDK 命令行界面（AWS 加密 CLI）使您能够使用在命令行和脚本中 AWS Encryption SDK 以交互方式加密和解密数据。您不需要具有加密或编程专业知识。

**注意**  
[4.0.0 之前的 AWS 加密 CLI 版本处于该阶段。end-of-support](https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html#version-life-cycle)  
您无需更改任何代码或数据即可安全地从 AWS Encryption CLI 版本 2.1.*x* 及更高版本更新为最新版本。但是，版本 2.1.*x* 中引入了[新的安全功能](about-versions.md#version-2)，不向后兼容。从 1.7 版本更新。 *x* 或更早版本，必须先更新到最新的 1。 AWS 加密 CLI 的 *x* 版本。有关更多信息，请参阅 [迁移你的 AWS Encryption SDK](migration.md)。  
新的安全功能最初是在 AWS 加密 CLI 版本 1.7 中发布的。 *x* 和 2.0。 *x*。但是， AWS 加密 CLI 版本为 1.8。 *x* 取代了 1.7 版。 *x* 和 AWS 加密 CLI 2.1。 *x* 取代 2.0。 *x*。有关详细信息，请参阅[aws-encryption-sdk-cli](https://github.com/aws/aws-encryption-sdk-cli/)存储库中的相关[安全公告](https://github.com/aws/aws-encryption-sdk-cli/security/advisories/GHSA-2xwp-m7mq-7q3r) GitHub。

与的所有实现一样 AWS Encryption SDK， AWS 加密 CLI 提供高级数据保护功能。这些功能包括[信封加密](https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/how-it-works.html#envelope-encryption)、额外验证数据（AAD）以及经过身份验证的安全对称密钥[算法套件](https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/supported-algorithms.html)，例如，具有密钥派生、[密钥承诺](concepts.md#key-commitment)和签名的 256 位 AES-GCM。

 AWS 加密 CLI 建立在 Linux、macOS [AWS Encryption SDK for Python](python.md)和 Windows 上，并受其支持。你可以在 Linux 或 macOS 的首选 shell 中、Windows 的命令提示符窗口 (cmd.exe) 以及任何系统的 PowerShell 控制台中运行命令和脚本来加密和解密数据。

的所有特定于语言的实现 AWS Encryption SDK，包括加密 AWS CLI，均可互操作。例如，您可以使用加密数据，使用加密 AWS CLI 对其进行解密。[AWS Encryption SDK for Java](java.md)

本主题介绍了 AWS 加密 CLI，解释了如何安装和使用它，并提供了几个示例来帮助您入门。要快速入门，请参阅 AWS 安全博客中的[如何使用加密 AWS CLI 加密和解密您的数据](https://aws.amazon.com/blogs/security/how-to-encrypt-and-decrypt-your-data-with-the-aws-encryption-cli/)。有关更多详细信息，请参阅[阅读文档](https://aws-encryption-sdk-cli.readthedocs.io/en/latest/)，并加入我们在[aws-encryption-sdk-cli](https://github.com/aws/aws-encryption-sdk-cli/)存储库中开发 AWS Encryption CLI GitHub。

**性能**  
加 AWS 密 CLI 建立在 AWS Encryption SDK for Python。每次运行 CLI 时，都会启动新的 Python 运行时实例。为了提高性能，请尽可能使用单个命令而不是一系列单独的命令。例如，运行一个递归处理目录中的文件的命令，而不是为每个文件运行单独的命令。

**Topics**
+ [安装 CLI](crypto-cli-install.md)
+ [如何使用 CLI](crypto-cli-how-to.md)
+ [示例](crypto-cli-examples.md)
+ [语法和参数参考](crypto-cli-reference.md)
+ [版本](crypto-cli-versions.md)

# 安装 AWS Encryption SDK 命令行界面
<a name="crypto-cli-install"></a>

本主题介绍如何安装 AWS 加密 CLI。有关详细信息，请参阅上的[aws-encryption-sdk-cli](https://github.com/aws/aws-encryption-sdk-cli/)存储库 GitHub 和 [Read the Docs](https://aws-encryption-sdk-cli.readthedocs.io/en/latest/)。

**Topics**
+ [

## 安装必备组件
](#crypto-cli-prerequisites)
+ [安装 CLI](#install-sdk-cli)

## 安装必备组件
<a name="crypto-cli-prerequisites"></a>

加 AWS 密 CLI 建立在 AWS Encryption SDK for Python。要安装 AWS 加密 CLI，你需要 Python 和 `pip` Python 包管理工具。可以在所有支持的平台上使用 Python 和 `pip`。

在安装 AWS 加密 CLI 之前，请安装以下必备组件，

**Python**  
 AWS 加密 CLI 版本 4.2.0 及更高版本需要 Python 3.8 或更高版本。  
早期版本的 AWS 加密 CLI 支持 Python 2.7 和 3.4 及更高版本，但我们建议您使用最新版本的 AWS 加密 CLI。  
大多数 Linux 和 macOS 安装中都包含 Python，但您需要升级到 Python 3.6 或更高版本。建议您使用最新的 Python 版本。在 Windows 上，您必须安装 Python；默认未安装。要下载并安装 Python，请参阅 [Python downloads](https://www.python.org/downloads/)。  
要确定是否安装了 Python，请在命令行中键入以下内容：  

```
python
```
要检查 Python 版本，请使用 `-V`（大写 V）参数。  

```
python -V
```
在 Windows 上，在安装 Python 之后，将 `Python.exe` 文件的路径添加到**路径**环境变量的值中。  
默认情况下，Python 安装在所有用户目录中，或者安装在 `$home` 子目录的用户配置文件目录（`%userprofile%` 或 `AppData\Local\Programs\Python`）中。要在您的系统上查找 `Python.exe` 文件的位置，请检查以下注册表项之一。您可以使用 PowerShell 搜索注册表。  

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

**pip**  
`pip` 是 Python 程序包管理器。要安装 AWS 加密 CLI 及其依赖项，你需要 `pip` 8.1 或更高版本。有关安装或升级 `pip` 的帮助，请参阅 `pip` 文档中的 [Installation](https://pip.pypa.io/en/latest/installing/)。  
**在 Linux 安装中，8.1 `pip` 之前的版本无法构建 AWS 加密 CLI 所需的加密库。**如果您选择不更新 `pip` 版本，可以单独安装构建工具。有关更多信息，请参阅[在 Linux 上构建加密](https://cryptography.io/en/latest/installation.html#building-cryptography-on-linux)。

**AWS Command Line Interface**  
只有在 AWS 加密 CLI AWS KMS keys 中使用 in AWS Command Line Interface (AWS CLI) 时， AWS Key Management Service (AWS KMS) 才是必需的。如果您使用的是不同的[主密钥提供程序](concepts.md#master-key-provider)，则 AWS CLI 不是必需的。  
要 AWS KMS keys 与 AWS 加密 CLI 配合使用，您需要[安装](https://docs.aws.amazon.com/cli/latest/userguide/installing.html)和[配置](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html#cli-quick-configuration) AWS CLI。该配置使您用于进行身份验证的凭据 AWS KMS 可供 AWS 加密 CLI 使用。

## 安装和更新 AWS 加密 CLI
<a name="install-sdk-cli"></a>

安装最新版本的 AWS 加密 CLI。当你使用`pip`安装 AWS 加密 CLI 时，它会自动安装 CLI 所需的库，包括 Python [加密库](https://cryptography.io/en/latest/)和。[AWS Encryption SDK for Python[适用于 Python (Boto3) 的 AWS SDK](https://boto3.amazonaws.com/v1/documentation/api/latest/index.html)](python.md)

**注意**  
[4.0.0 之前的 AWS 加密 CLI 版本处于该阶段。end-of-support](https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html#version-life-cycle)  
您无需更改任何代码或数据即可安全地从 AWS Encryption CLI 版本 2.1.*x* 及更高版本更新为最新版本。但是，版本 2.1.*x* 中引入了[新的安全功能](about-versions.md#version-2)，不向后兼容。从 1.7 版本更新。 *x* 或更早版本，必须先更新到最新的 1。 AWS 加密 CLI 的 *x* 版本。有关更多信息，请参阅 [迁移你的 AWS Encryption SDK](migration.md)。  
新的安全功能最初是在 AWS 加密 CLI 版本 1.7 中发布的。 *x* 和 2.0。 *x*。但是， AWS 加密 CLI 版本为 1.8。 *x* 取代了 1.7 版。 *x* 和 AWS 加密 CLI 2.1。 *x* 取代 2.0。 *x*。有关详细信息，请参阅[aws-encryption-sdk-cli](https://github.com/aws/aws-encryption-sdk-cli/)存储库中的相关[安全公告](https://github.com/aws/aws-encryption-sdk-cli/security/advisories/GHSA-2xwp-m7mq-7q3r) GitHub。

**安装最新版本的 AWS 加密 CLI**  

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

**升级到最新版本的 AWS 加密 CLI**  

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

**要查找您的 AWS 加密 CLI 的版本号和 AWS Encryption SDK**  

```
aws-encryption-cli --version
```
输出列出了两个库的版本号。  

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

**升级到最新版本的 AWS 加密 CLI**  

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

安装 AWS 加密 CLI 时还会安装最新版本的（如果尚未安装的话）。 适用于 Python (Boto3) 的 AWS SDK如果安装了 Boto3，安装程序会验证 Boto3 版本并在需要时对其进行更新。

**查找您安装的 Boto3 版本**  

```
pip show boto3
```

**更新为最新版本的 Boto3**  

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

要安装当前正在开发的 Enc AWS ryption CLI 版本，请查看上的[aws-encryption-sdk-cli](https://github.com/aws/aws-encryption-sdk-cli/)存储库 GitHub。

有关使用 `pip` 安装和升级 Python 程序包的更多详细信息，请参阅 [pip 文档](https://pip.pypa.io/en/stable/quickstart/)。

# 如何使用 AWS 加密 CLI
<a name="crypto-cli-how-to"></a>

本主题介绍如何使用 AWS 加密 CLI 中的参数。有关示例，请参阅 [AWS 加密 CLI 的示例](crypto-cli-examples.md)。有关完整文档，请参阅[阅读文档](https://aws-encryption-sdk-cli.readthedocs.io/en/latest/)。这些示例中显示的语法适用于 AWS 加密 CLI 版本 2.1。 *x* 及更高版本。

**注意**  
[4.0.0 之前的 AWS 加密 CLI 版本处于该阶段。end-of-support](https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html#version-life-cycle)  
您无需更改任何代码或数据即可安全地从 AWS Encryption CLI 版本 2.1.*x* 及更高版本更新为最新版本。但是，版本 2.1.*x* 中引入了[新的安全功能](about-versions.md#version-2)，不向后兼容。从 1.7 版本更新。 *x* 或更早版本，必须先更新到最新的 1。 AWS 加密 CLI 的 *x* 版本。有关更多信息，请参阅 [迁移你的 AWS Encryption SDK](migration.md)。  
新的安全功能最初是在 AWS 加密 CLI 版本 1.7 中发布的。 *x* 和 2.0。 *x*。但是， AWS 加密 CLI 版本为 1.8。 *x* 取代了 1.7 版。 *x* 和 AWS 加密 CLI 2.1。 *x* 取代 2.0。 *x*。有关详细信息，请参阅[aws-encryption-sdk-cli](https://github.com/aws/aws-encryption-sdk-cli/)存储库中的相关[安全公告](https://github.com/aws/aws-encryption-sdk-cli/security/advisories/GHSA-2xwp-m7mq-7q3r) GitHub。

有关展示如何使用限制加密数据密钥的安全功能的示例，请参阅 [限制加密数据密钥](configure.md#config-limit-keys)。

有关展示如何使用 AWS KMS 多区域密钥的示例，请参阅[使用多区域 AWS KMS keys](configure.md#config-mrks)。

**Topics**
+ [

## 如何加密和解密数据
](#crypto-cli-e-d-intro)
+ [

## 如何指定包装密钥
](#crypto-cli-master-key)
+ [

## 如何提供输入
](#crypto-cli-input)
+ [

## 如何指定输出位置
](#crypto-cli-output)
+ [

## 如何使用加密上下文
](#crypto-cli-encryption-context)
+ [

## 如何指定承诺策略
](#crypto-cli-commitment-policy)
+ [

## 如何在配置文件中存储参数
](#crypto-cli-config-file)

## 如何加密和解密数据
<a name="crypto-cli-e-d-intro"></a>

加 AWS 密 CLI 使用的功能 AWS Encryption SDK ，可以轻松安全地加密和解密数据。

**注意**  
`--master-keys` 参数在 AWS Encryption CLI 版本 1.8.*x* 中弃用并在版本 2.1.*x* 中删除。请改用 `--wrapping-keys` 参数。从版本 2.1.*x* 开始，加密和解密时需要使用 `--wrapping-keys` 参数。有关更多信息，请参阅 [AWS Encryption SDK CLI 语法和参数参考](crypto-cli-reference.md)。
+ 在加密 CLI 中 AWS 加密数据时，需要指定您的纯文本数据和[包装密钥](concepts.md#master-key)（或*主密钥*），例如 AWS KMS key in AWS Key Management Service (AWS KMS)。如果使用自定义主密钥提供程序，您还需要指定该提供程序。您还需要指定[加密的消息](concepts.md#message)以及有关加密操作的元数据的输出位置。[加密上下文](concepts.md#encryption-context)是可选的，但建议使用。

  在版本 1.8.*x* 中，使用 `--wrapping-keys` 参数时需要使用 `--commitment-policy` 参数；否则该参数无效。从版本 2.1.*x* 开始，`--commitment-policy` 参数是可选的，但建议使用。

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

   AWS 加密 CLI 使用唯一的数据密钥对您的数据进行加密。然后，对您指定的包装密钥下的数据密钥进行加密。它返回[加密的消息](concepts.md#message)以及有关该操作的元数据。加密的消息包含加密的数据（*密文*）以及数据密钥的加密副本。您不必担心数据密钥存储、管理或丢失问题。

   
+ 在解密数据时，您将传入加密的消息、可选的加密上下文以及明文输出和元数据位置。您还可以指定 AWS 加密 CLI 可以用来解密邮件的包装密钥，或者告诉 Encryption AWS CLI 它可以使用任何对邮件进行加密的包装密钥。

  从版本 1.8.*x* 开始，`--wrapping-keys` 参数在解密时是可选的，但建议使用。从版本 2.1.*x* 开始，加密和解密时需要使用 `--wrapping-keys` 参数。

  解密时，您可以使用 `--wrapping-keys` 参数的 **key** 属性来指定用于解密数据的包装密钥。在解密时指定 AWS KMS 包装密钥是可选的，但这是一种[最佳做法](best-practices.md)，可以防止您使用本来不打算使用的密钥。如果使用自定义主密钥提供程序，您必须指定该提供程序和包装密钥。

  如果您不使用**密钥**属性，则必须将`--wrapping-keys`参数的[**发现**属性](#discovery-cli-attribute)设置为，这样`true`，Encryption CLI 就可以使用 AWS 加密邮件的任何包装密钥进行解密。

  最佳实践是使用 `--max-encrypted-data-keys` 参数来避免使用过多的加密数据密钥解密格式错误的消息。指定预期的加密数据密钥数量（加密中使用的每个包装密钥各一个）或合理的最大值（例如 5）。有关更多信息，请参阅 [限制加密数据密钥](configure.md#config-limit-keys)。

  只有在处理完所有输入之后，`--buffer` 参数才会返回明文，包括验证数字签名（如果存在）。

  `--decrypt-unsigned` 参数对加密文字进行解密并确保消息在解密之前未签名。如果您使用 `--algorithm` 参数并选择了不带数字签名的算法套件来加密数据，请使用此参数。如果加密文字已签名，则解密失败。

  您可以使用 `--decrypt` 或 `--decrypt-unsigned` 进行解密，但不能同时使用两者。

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

  加 AWS 密 CLI 使用包装密钥来解密加密消息中的数据密钥。然后，它使用数据密钥解密数据。它返回明文数据以及有关该操作的元数据。

## 如何指定包装密钥
<a name="crypto-cli-master-key"></a>

在加密 CLI 中 AWS 加密数据时，需要至少指定一个[封装密钥](concepts.md#master-key)（或*主密钥*）。您可以 AWS KMS keys 在 AWS Key Management Service (AWS KMS) 中使用、包装来自自定义[主密钥提供程序的密钥](concepts.md#master-key-provider)，或者两者兼而有之。自定义主密钥提供程序可以是任何兼容的 Python 主密钥提供程序。

要在版本 1.8.*x* 及以后的版本中指定包装密钥，请使用 `--wrapping-keys` 参数 (`-w`)。该参数的值是具有 `attribute=value` 格式的[属性](#cli-master-key-attributes)集合。您使用的属性取决于主密钥提供程序和命令。
+ **AWS KMS**。在加密命令中，您必须指定具有 **key** 属性的 `--wrapping-keys` 参数。从版本 2.1.*x* 开始，解密命令中也需要使用 `--wrapping-keys` 参数。解密时，`--wrapping-keys` 参数必须具有值为 `true` 的 **key** 属性或 **discovery** 属性（但不能两者同时使用）。其他属性是可选的。
+ **自定义主密钥提供程序**。您必须在每个命令中指定 `--wrapping-keys` 参数。该参数值必须具有 **key** 和 **provider** 属性。

您可以在同一命令中包含[多个 `--wrapping-keys` 参数](#cli-many-cmks)和多个 **key** 属性。

### 包装密钥参数属性
<a name="cli-master-key-attributes"></a>

`--wrapping-keys` 参数值包含以下属性及其值。所有加密命令都需要一个 `--wrapping-keys` 参数（或 `--master-keys` 参数）。从版本 2.1.*x* 开始，解密时也需要 `--wrapping-keys` 参数。

如果属性名称或值包含空格或特殊字符，请将名称和值用引号引起来。例如 `--wrapping-keys key=12345 "provider=my cool provider"`。

**密钥：指定包装密钥**  
使用 **key** 属性识别包装密钥。加密时，该值可以是主密钥提供程序识别的任何密钥标识符。  

```
--wrapping-keys key=1234abcd-12ab-34cd-56ef-1234567890ab
```
在加密命令中，您必须至少包含一个 **key** 属性和值。要在多个包装密钥下加密您的数据密钥，请使用[多个 **key** 属性](#cli-many-cmks)。  

```
aws-encryption-cli --encrypt --wrapping-keys key=1234abcd-12ab-34cd-56ef-1234567890ab key=1a2b3c4d-5e6f-1a2b-3c4d-5e6f1a2b3c4d
```
在使用的加密命令中 AWS KMS keys，**密钥**的值可以是密钥 ID、其密钥 ARN、别名或别名 ARN。例如，该 encrypt 命令在 **key** 属性值中使用别名 ARN。有关密钥标识符的详细信息 AWS KMS key，请参阅《*AWS Key Management Service 开发者指南*》中的[密钥标识符](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id)。  

```
aws-encryption-cli --encrypt --wrapping-keys key=arn:aws:kms:us-west-2:111122223333:alias/ExampleAlias
```
在使用自定义主密钥提供程序的 decrypt 命令中，需要使用 **key** 和 **provider** 属性。  

```
\\ Custom master key provider
aws-encryption-cli --decrypt --wrapping-keys provider='myProvider' key='100101'
```
在使用的解密命令中 AWS KMS，您可以使用密**钥**属性来指定用于解密的，或者使用值为的[**发现**属性 AWS KMS keys](#discovery-cli-attribute)来指定用于加密消息的`true`，允许加密 AWS CLI 使用任何用于加密 AWS KMS key 消息的属性。如果指定 AWS KMS key，则它必须是用于加密消息的包装密钥之一。  
指定包装密钥是 [AWS Encryption SDK 最佳实践](best-practices.md)。它可以确保你使用 AWS KMS key 你打算使用的。  
在解密命令中，**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
```

**发现：解密 AWS KMS key 时使用 any**  <a name="discovery-cli-attribute"></a>
如果您在解密时不需要限制使用 AWS KMS keys ，则可以使用值为的 d **iscovery** 属性。`true`值为`true`允许 AWS 加密 CLI 使用任何加密消息 AWS KMS key 的内容进行解密。如果不指定 **discovery** 属性，则发现为 `false`（默认值）。**发现**属性仅在解密命令中有效，并且仅当消息使用加密时才有效。 AWS KMS keys  
值为 `true` 的 **discovery** 属性可以替代使用 **key** 属性指定 AWS KMS keys。解密使用加密的消息时 AWS KMS keys，每个`--wrapping-keys`参数都必须有一个**密钥**属性或一个值为的**发现**属性`true`，但不能两者兼而有之。  
当发现属实时，最佳做法是使用**发现分区和**发现账户**属性将使用限制在您 AWS KMS keys 指定的范围**内。 AWS 账户 在以下示例中，**发现**属性允许 AWS 加密 CLI 使用指定 AWS KMS key 中的任何属性 AWS 账户。  

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

**提供程序：指定主密钥提供程序**  
**provider** 属性指定[主密钥提供程序](concepts.md#master-key-provider)。默认值为 `aws-kms`，它表示 AWS KMS。如果使用不同的主密钥提供程序，则需要使用 **provider** 属性。  

```
--wrapping-keys key=12345 provider=my_custom_provider
```
有关使用自定义（非AWS KMS）主密钥提供程序的更多信息，请参阅 [AWS Encryption CLI](https://github.com/aws/aws-encryption-sdk-cli/) 存储库的 [README](https://github.com/aws/aws-encryption-sdk-cli/blob/master/README.rst) 文件中的**高级配置**主题。

**区域：指定一个 AWS 区域**  
使用 re **gion** 属性来指定 AWS 区域 的 AWS KMS key。该属性仅在 encrypt 命令中有效，并且仅在主密钥提供程序为 AWS KMS时有效。  

```
--encrypt --wrapping-keys key=alias/primary-key region=us-east-2
```
AWS 如果加密 CLI 命令包含区域（例如 ARN），则使用**密钥**属性值中指定的。如果**密钥**值指定了 AWS 区域，则**区域**属性将被忽略。 AWS 区域   
**region** 属性优先于指定的其他区域。如果您不使用区域属性， AWS Encryption CLI 命令将使用您的 AWS CLI [命名配置文件](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html#cli-configure-files-using-profiles)（如果有）或默认配置文件中 AWS 区域 指定的属性。

**profile：指定命名配置文件**  
可以使用 **profile** 属性指定 AWS CLI [命名配置文件](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html#cli-configure-files-using-profiles)。命名配置文件可以包含凭证和 AWS 区域。只有在主密钥提供程序为 AWS KMS时，该属性才有效。  

```
--wrapping-keys key=alias/primary-key profile=admin-1
```
您可以使用 **profile** 属性在 encrypt 和 decrypt 命令中指定备用凭证。在加密命令 AWS 区域 中，只有当 AWS 密**钥**值不包括区域且没有**区域**属性时，Encryption CLI 才在命名配置文件中使用。在解密命令中，名称 AWS 区域 中的配置文件将被忽略。

### 如何指定多个包装密钥
<a name="cli-many-cmks"></a>

您可以在每个命令中指定多个包装密钥（或*主密钥*）。

如果指定多个包装密钥，第一个包装密钥将生成并加密用于加密数据的数据密钥。其他包装密钥对相同的数据密钥进行加密。生成的[加密消息](concepts.md#message)包含加密的数据（“加密文字”）以及一组加密的数据密钥，每个包装密钥加密一个数据密钥。任何包装密钥可以解密一个加密的数据密钥，然后解密数据。

可以通过两种方法指定多个包装密钥：
+ 在 `--wrapping-keys` 参数值中包含多个 **key** 属性。

  ```
  $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
  ```
+ 在同一命令中包含多个 `--wrapping-keys` 参数。如果您指定的属性值不适用于命令中的所有包装密钥，请使用该语法。

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

值为的**发现**属性`true`允许 AWS Encryption CLI 使用任何加密 AWS KMS key 消息的内容。如果您在同一个命令中使用多个 `--wrapping-keys` 参数，则在任何 `--wrapping-keys` 参数中使用 `discovery=true` 都会有效地覆盖其他 `--wrapping-keys` 参数中 **key** 属性的限制。

例如，在以下命令中，第一个`--wrapping-keys`参数中的**密钥**属性将 AWS 加密 CLI 限制为指定的 AWS KMS key。但是，第二个`--wrapping-keys`参数中的**发现**属性允许 AWS Encryption CLI 使用指定账户 AWS KMS key 中的任意账户来解密邮件。

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

## 如何提供输入
<a name="crypto-cli-input"></a>

加密 CLI 中的 AWS 加密操作将纯文本数据作为输入并返回[加密](concepts.md#message)消息。解密操作将加密的消息作为输入，并返回明文数据。

所有 AWS 加密 CLI 命令都需要`--input`参数 (`-i`)，它告诉加 AWS 密 CLI 在哪里可以找到输入。

您可以通过任何以下方法提供输入：
+ 使用文件。

  ```
  --input myData.txt
  ```
+ 使用文件名模式。

  ```
  --input testdir/*.xml
  ```
+ 使用目录或目录名称模式。在输入为目录时，需要使用 `--recursive` 参数 (`-r`, `-R`)。

  ```
  --input testdir --recursive
  ```
+ 通过管道将输入发送到命令 (stdin)。请使用 `-` 参数的值 `--input`。（`--input` 参数始终是必需的。）

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

## 如何指定输出位置
<a name="crypto-cli-output"></a>

该`--output`参数告诉 AWS 加密 CLI 在哪里写加密或解密操作的结果。每个 AWS 加密 CLI 命令都需要它。 AWS Encryption CLI 为操作中的每个输入文件创建新的输出文件。

如果输出文件已经存在，则默认情况下， AWS 加密 CLI 会打印警告，然后覆盖该文件。要禁止覆盖，请使用 `--interactive` 参数（在覆盖之前提示您确认）或 `--no-overwrite`（在输出导致覆盖时跳过输入）。要禁止显示覆盖警告，请使用 `--quiet`。要从 Encryption C AWS LI 中捕获错误和警告，请使用`2>&1`重定向运算符将其写入输出流。

**注意**  
覆盖输出文件的命令先删除输出文件。如果该命令失败，则可能已删除输出文件。

您可以通过多种方法指定输出位置。
+ 指定文件名。如果指定文件的路径，在运行该命令之前，路径中的所有目录必须存在。

  ```
  --output myEncryptedData.txt
  ```
+ 指定目录。在运行该命令之前，输出目录必须存在。

  如果输入包含子目录，该命令将在指定的目录中重新生成这些子目录。

  ```
  --output Test
  ```

  当输出位置为目录（不含文件名）时， AWS Encryption CLI 会根据输入文件名和后缀创建输出文件名。加密操作将 `.encrypted` 附加到输入文件名后面，而解密操作附加 `.decrypted`。要更改后缀，请使用 `--suffix` 参数。

  例如，如果加密 `file.txt`，encrypt 命令将创建 `file.txt.encrypted`。如果解密 `file.txt.encrypted`，decrypt 命令将创建 `file.txt.encrypted.decrypted`。

   
+ 写入到命令行 (stdout)。为 `-` 参数输入值 `--output`。您可以使用 `--output -` 通过管道将输出发送到另一个命令或程序。

  ```
  --output -
  ```

## 如何使用加密上下文
<a name="crypto-cli-encryption-context"></a>

加 AWS 密 CLI 允许您在加密和解密命令中提供加密上下文。这不是必需的，但这是我们建议的加密最佳实践。

*加密上下文* 是一种任意的非机密*其他经过身份验证的数据*。在 AWS Encryption CLI 中，加密上下文包含一组 `name=value` 对。您可以在对中使用任意内容，包括有关文件的信息、帮助您在日志中查找加密操作的数据或您的授权或策略所需的数据。

**在 encrypt 命令中**

在 encrypt 命令中指定的加密上下文以及 [CMM](concepts.md#crypt-materials-manager) 添加的任何其他对以加密方式绑定到加密的数据。它还包含（以明文形式）在该命令返回的[加密的消息](concepts.md#encryption-context)中。如果您使用的是 AWS KMS key，加密上下文也可能以纯文本形式出现在审计记录和日志中，例如。 AWS CloudTrail

以下示例显示具有三个 `name=value` 对的加密上下文。

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

**在 decrypt 命令中**

在 decrypt 命令中，加密上下文帮助您确认解密的是正确的加密消息。

不需要在 decrypt 命令中提供加密上下文，即使在加密时使用了加密上下文。但是，如果这样做， AWS Encryption CLI 会验证 decrypt 命令的加密上下文中的每个元素是否都与加密邮件的加密上下文中的元素相匹配。如果任何元素不匹配，decrypt 命令将失败。

例如，只有在加密上下文包含 `dept=IT` 时，以下命令才会解密加密的消息。

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

加密上下文是安全策略的重要组成部分。不过，在选择加密上下文时，请记住它的值不是机密的。请不要在加密上下文中包含任何机密数据。

**指定加密上下文**
+ 在 **encrypt** 命令中，使用具有一个或多个 `name=value` 对的 `--encryption-context` 参数。请使用空格分隔每个对。

  ```
  --encryption-context name=value [name=value] ...
  ```
+ 在 **decrypt** 命令中，`--encryption-context` 参数值可以包含 `name=value` 对、`name` 元素（没有值）或两者的组合。

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

如果 `name` 对中的 `value` 或 `name=value` 包含空格或特殊字符，请将整个对用引号引起来。

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

例如，该 encrypt 命令包含具有两个对（`purpose=test` 和 `dept=23`）的加密上下文。

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

这些 decrypt 命令将会成功。每个命令中的加密上下文是原始加密上下文的一部分。

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

不过，这些 decrypt 命令将会失败。加密的消息中的加密上下文不包含指定的元素。

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

## 如何指定承诺策略
<a name="crypto-cli-commitment-policy"></a>

要为命令设置[承诺策略](concepts.md#commitment-policy)，请使用 [`--commitment-policy` 参数](crypto-cli-reference.md#syntax-commitment-policy)。此参数在版本 1.8.*x* 中引入。该参数在加密和解密命令中有效。您设置的承诺策略仅对出现在其中的命令有效。如果您没有为命令设置承诺策略，则 AWS 加密 CLI 将使用默认值。

例如，以下参数值将承诺策略设置为 `require-encrypt-allow-decrypt`，该策略始终使用密钥承诺进行加密，但会解密使用或不使用密钥承诺加密的加密文字。

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

## 如何在配置文件中存储参数
<a name="crypto-cli-config-file"></a>

通过将常用的 Encryption CLI 参数和值保 AWS 存在配置文件中，可以节省时间并避免键入错误。

*配置文件*是一个文本文件，其中包含 AWS 加密 CLI 命令的参数和值。在 AWS Encryption CLI 命令中引用配置文件时，引用将替换为配置文件中的参数和值。如果在命令行中键入文件内容，效果是相同的。配置文件可以具有任何名称，并且可以位于当前用户可访问的任何目录中。

以下示例配置文件 (`key.conf`) 指定不同区域中的两个 AWS KMS keys 。

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

要在命令中使用配置文件，请在文件名前面添加 at 符号 (`@`)。在 PowerShell 主机中，使用反引号字符对 at 符号 (``@`) 进行转义。

以下示例命令在 encrypt 命令中使用 `key.conf` 文件。

------
#### [ 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
```

------

**配置文件规则**

使用配置文件的规则如下所示：
+ 您可以在每个配置文件中包含多个参数，并按任意顺序列出这些参数。请在单独一行中列出每个参数及其值（如果有）。
+ 使用 `#` 为一行的全部或部分内容添加注释。
+ 您可以包含对其他配置文件的引用。即使在，也不要使用反引号逃避`@`标志。 PowerShell
+ 如果在配置文件中使用引号，引起来的文本不能跨多个行。

例如，以下是示例 `encrypt.conf` 文件的内容。

```
# 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
```

也可以在命令中包含多个配置文件。以下示例命令使用 `encrypt.conf` 和 `master-keys.conf` 配置文件。

------
#### [ 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
```

------

**下一步：**[试用 AWS Encryption CLI 示例](crypto-cli-examples.md)

# AWS 加密 CLI 的示例
<a name="crypto-cli-examples"></a>

使用以下示例在您喜欢的平台上试用 AWS 加密 CLI。有关主密钥和其他参数的帮助，请参阅[如何使用 AWS 加密 CLI](crypto-cli-how-to.md)。有关快速参考，请参阅 [AWS Encryption SDK CLI 语法和参数参考](crypto-cli-reference.md)。

**注意**  
以下示例使用 AWS 加密 CLI 版本 2.1 的语法。 *x*。  
新的安全功能最初是在 AWS 加密 CLI 版本 1.7 中发布的。 *x* 和 2.0。 *x*。但是， AWS 加密 CLI 版本为 1.8。 *x* 取代了 1.7 版。 *x* 和 AWS 加密 CLI 2.1。 *x* 取代 2.0。 *x*。有关详细信息，请参阅[aws-encryption-sdk-cli](https://github.com/aws/aws-encryption-sdk-cli/)存储库中的相关[安全公告](https://github.com/aws/aws-encryption-sdk-cli/security/advisories/GHSA-2xwp-m7mq-7q3r) GitHub。

有关展示如何使用限制加密数据密钥的安全功能的示例，请参阅 [限制加密数据密钥](configure.md#config-limit-keys)。

有关如何使用 AWS KMS 多区域密钥的示例，请参阅[使用多区域 AWS KMS keys](configure.md#config-mrks)。

**Topics**
+ [

## 加密文件
](#cli-example-encrypt-file)
+ [

## 解密文件
](#cli-example-decrypt-file)
+ [

## 加密目录中的所有文件
](#cli-example-encrypt-directory)
+ [

## 解密目录中的所有文件
](#cli-example-decrypt-directory)
+ [

## 在命令行上加密和解密
](#cli-example-stdin)
+ [

## 使用多个主密钥
](#cli-example-multimaster)
+ [

## 在脚本中加密和解密
](#cli-example-script)
+ [

## 使用数据密钥缓存
](#cli-example-caching)

## 加密文件
<a name="cli-example-encrypt-file"></a>

此示例使用 AWS 加密 CLI 对文件内容进行加密，该`hello.txt`文件包含 “Hello World” 字符串。

当您对文件运行加密命令时， AWS Encryption CLI 会获取文件内容，生成唯一[的数据密钥](concepts.md#DEK)，加密数据密钥下的文件内容，然后将[加密的消息](concepts.md#message)写入新文件。

第一个命令将的密钥 ARN 保存在变量 AWS KMS key 中。`$keyArn`使用加密时 AWS KMS key，您可以使用密钥 ID、密钥 ARN、别名或别名 ARN 来识别它。有关密钥标识符的详细信息 AWS KMS key，请参阅《*AWS Key Management Service 开发者指南*》中的[密钥标识符](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id)。

第二个命令加密文件内容。该命令使用 `--encrypt` 参数指定操作，并使用 `--input` 参数指示要加密的文件。[`--wrapping-keys`参数](crypto-cli-how-to.md#crypto-cli-master-key)及其必需的**密钥**属性告诉命令使用由密钥 ARN AWS KMS key 表示的。

该命令使用 `--metadata-output` 参数指定一个包含有关加密操作的元数据的文本文件。作为最佳实践，该命令使用 `--encryption-context` 参数指定一个[加密上下文](crypto-cli-how-to.md#crypto-cli-encryption-context)。

此命令还使用 [`--commitment-policy` 参数](crypto-cli-reference.md#syntax-commitment-policy)来明确设置承诺策略。在版本 1.8.*x* 中，当您使用 `--wrapping-keys` 参数时，需要使用这个参数。从版本 2.1.*x* 开始，`--commitment-policy` 参数是可选的，但建议使用。

`--output` 参数的值“句点”(.) 指示命令将输出文件写入到当前目录中。

------
#### [ 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 .
```

------

如果 encrypt 命令成功，它不返回任何输出。要确定该命令是否成功，请检查 `$?` 变量中的布尔值。命令成功后，的值`$?`为 `0` (Bash) 或 `True` (PowerShell)。命令失败时，的值`$?`为非零 (Bash) 或 `False` (PowerShell)。

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

```
$ echo $?
0
```

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

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

------

也可以使用目录列表命令查看 encrypt 命令是否创建了新的文件 (`hello.txt.encrypted`)。由于 encrypt 命令没有为输出指定文件名，因此 AWS Encryption CLI 会将输出写入一个与输入文件同名并带有`.encrypted`后缀的文件中。要使用不同的后缀或忽略后缀，请使用 `--suffix` 参数。

`hello.txt.encrypted` 文件包含[加密的消息](concepts.md#message)，其中包含 `hello.txt` 文件的密文、数据密钥的加密副本以及额外的元数据（包括加密上下文）。

------
#### [ 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
```

------

## 解密文件
<a name="cli-example-decrypt-file"></a>

此示例使用 AWS 加密 CLI 来解密前面示例中加密`Hello.txt.encrypted`的文件内容。

decrypt 命令使用 `--decrypt` 参数指示操作，并使用 `--input` 参数指定要解密的文件。`--output` 参数的值是一个句点，表示当前的目录。

带有 **key** 属性的 `--wrapping-keys` 参数指定用于解密加密消息的包装密钥。在使用解密命令中 AWS KMS keys，密钥属性的值必须是密钥 [AR](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id-key-ARN) N。在解密命令中需要使用 `--wrapping-keys` 参数。如果您正在使用 AWS KMS keys，则可以使用 **key** 属性来指定 AWS KMS keys 用于解密，也可以使用值为 `true` 的 **discovery** 属性（但不能两者同时使用）。如果使用自定义主密钥提供程序，则需要使用 **key** 和 **provider** 属性。

从版本 2.1.*x* 开始，[`--commitment-policy` 参数](crypto-cli-reference.md#syntax-commitment-policy)是可选的，但建议使用。即使您指定了默认值 `require-encrypt-require-decrypt`，也可以明确使用该参数来明确您的意图。

`--encryption-context` 参数在 decrypt 命令中是可选的，即使在 encrypt 命令中提供了[加密上下文](crypto-cli-how-to.md#crypto-cli-encryption-context)。在这种情况下，decrypt 命令使用在 encrypt 命令中提供的相同加密上下文。在解密之前，Encryption CL AWS I 会验证加密消息中的加密上下文是否包含一对。`purpose=test`如果不包含，decrypt 命令将失败。

`--metadata-output` 参数指定一个包含有关解密操作的元数据的文件。`--output` 参数的值“句点”(.) 指示将输出文件写入到当前目录中。

最佳实践是使用 `--max-encrypted-data-keys` 参数来避免使用过多的加密数据密钥解密格式错误的消息。指定预期的加密数据密钥数量（加密中使用的每个包装密钥各一个）或合理的最大值（例如 5）。有关更多信息，请参阅 [限制加密数据密钥](configure.md#config-limit-keys)。

只有在处理完所有输入之后，`--buffer` 才会返回明文，包括验证数字签名（如果存在）。

------
#### [ 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 .
```

------

如果 decrypt 命令成功，它不返回任何输出。要确定该命令是否成功，请获取 `$?` 变量值。也可以使用目录列表命令查看该命令是否创建了具有 `.decrypted` 后缀的新文件。要查看明文内容，请使用一个命令以获取文件内容，例如 `cat` 或 [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
```

------

## 加密目录中的所有文件
<a name="cli-example-encrypt-directory"></a>

此示例使用 AWS 加密 CLI 对目录中所有文件的内容进行加密。

当一个命令影响多个文件时， AWS 加密 CLI 会单独处理每个文件。它获取文件内容，从主密钥中获取文件的唯一[数据密钥](concepts.md#DEK)，使用该数据密钥加密文件内容，然后将结果写入到输出目录的新文件中。因此，您可以单独解密这些输出文件。

以下 `TestDir` 目录列表显示我们要加密的明文文件。

------
#### [ 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
```

------

第一个命令将的 [Amazon 资源名称 (ARN)](https://docs.aws.amazon.com/kms/latest/developerguide/viewing-keys.html#find-cmk-id-arn) 保存在变量 AWS KMS key 中。`$keyArn`

第二个命令加密 `TestDir` 目录中的文件内容，并将包含加密内容的文件写入到 `TestEnc` 目录中。如果 `TestEnc` 目录不存在，该命令将失败。由于输入位置是一个目录，因此，`--recursive` 参数是必需的。

[`--wrapping-keys` 参数](crypto-cli-how-to.md#crypto-cli-master-key)及其所需的 **key** 属性指定要使用的包装密钥。encrypt 命令包含一个[加密上下文](crypto-cli-how-to.md#crypto-cli-encryption-context) (`dept=IT`)。如果在加密多个文件的命令中指定加密上下文，将在所有文件中使用相同的加密上下文。

该命令还有一个`--metadata-output`参数，用于告诉 AWS Encryption CLI 在哪里写入有关加密操作的元数据。加 AWS 密 CLI 为每个加密文件写入一条元数据记录。

从版本 2.1.*x* 开始，[`--commitment-policy parameter`](crypto-cli-how-to.md#crypto-cli-commitment-policy) 是可选的，但建议使用。如果命令或脚本因无法解密加密文字而失败，则显式承诺策略设置可以帮助您快速检测问题。

命令完成后， AWS 加密 CLI 会将加密文件写入该`TestEnc`目录，但不会返回任何输出。

最后一个命令列出 `TestEnc` 目录中的文件。每个包含明文内容的输入文件具有一个包含加密内容的输出文件。由于该命令未指定替代后缀，因此，encrypt 命令将 `.encrypted` 附加到每个输入文件名称后面。

------
#### [ 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
```

------

## 解密目录中的所有文件
<a name="cli-example-decrypt-directory"></a>

该示例解密目录中的所有文件。它从 `TestEnc` 目录中在上一个示例中加密的文件开始。

------
#### [ 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
```

------

此 decrypt 命令解密目录中的所有文件，并将纯文本文件写入该 TestEnc 目录。 TestDec 带有**密钥属性和密钥** [ARN](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id-key-ARN) 值的`--wrapping-keys`参数告诉加密 AWS CLI 使用哪个 AWS KMS keys 来解密文件。该命令使用`--interactive`参数告诉 AWS 加密 CLI 在覆盖同名文件之前提示您。

该命令还使用在加密文件时提供的加密上下文。解密多个文件时，加密 AWS CLI 会检查每个文件的加密上下文。如果对任何文件的加密上下文检查失败， AWS Encryption CLI 会拒绝该文件，写入警告，在元数据中记录失败，然后继续检查其余文件。如果 AWS 加密 CLI 由于任何其他原因无法解密文件，则整个 decrypt 命令将立即失败。

在该示例中，所有输入文件中的加密消息包含 `dept=IT` 加密上下文元素。不过，如果解密的消息具有不同的加密上下文，您仍然可以验证加密上下文部分。例如，如果某些消息具有 `dept=finance` 加密上下文，而其他消息具有 `dept=IT` 加密上下文，您可以确认加密上下文始终包含未指定值的 `dept` 名称。如果要了解更具体的信息，您可以在单独的命令中解密这些文件。

decrypt 命令不返回任何输出，但您可以使用目录列表命令查看它是否创建了具有 `.decrypted` 后缀的新文件。要查看明文内容，请使用一个命令以获取文件内容。

------
#### [ 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
```

------

## 在命令行上加密和解密
<a name="cli-example-stdin"></a>

以下示例介绍了如何通过管道将输入发送到命令 (stdin)，以及将输出写入到命令行 (stdout)。这些示例说明了如何在命令中表示 stdin 和 stdout，以及如何使用内置的 Base64 编码工具防止 shell 错误地解释非 ASCII 字符。

该示例通过管道将明文字符串发送到 encrypt 命令，并将加密的消息保存在变量中。然后，它通过管道将变量中的加密消息发送到 decrypt 命令，后者将其输出写入到管道中 (stdout)。

该示例包含以下三个命令：
+ 第一个命令将的[密钥 ARN](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id-key-ARN) 保存在变量 AWS KMS key 中。`$keyArn`

------
#### [ 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'
  ```

------

   
+ 第二个命令通过管道将 `Hello World` 字符串发送到 encrypt 命令，并将结果保存在 `$encrypted` 变量中。

  在所有 AWS Encryption CLI 命令中需要使用 `--input` 和 `--output` 参数。要指示通过管道将输入发送到命令 (stdin)，请将连字符 (`-`) 作为 `--input` 参数值。要将输出发送到命令行 (stdout)，请将连字符作为 `--output` 参数值。

  `--encode` 参数在返回输出之前对其进行 Base64 编码。这可防止 shell 错误地解释加密消息中的非 ASCII 字符。

  由于该命令只是概念验证，因此，我们省略加密上下文并忽略元数据 (`-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
  ```

------

   
+ 第三个命令通过管道将 `$encrypted` 变量中的加密消息发送到 decrypt 命令。

  该 decrypt 命令使用 `--input -` 指示输入来自于管道 (stdin)，并使用 `--output -` 将输出发送到管道 (stdout)。（input 参数使用输入位置而不是实际输入字节，因此，您不能将 `$encrypted` 变量作为 `--input` 参数值。） 

  此示例使用`--wrapping-keys`参数的**发现**属性允许 AWS Encryption CLI 使用任何属性 AWS KMS key 来解密数据。该示例没有指定[承诺策略](concepts.md#commitment-policy)，因此使用版本 2.1.*x* 及更高版本的默认值 `require-encrypt-require-decrypt`。

  由于输出已加密并随后进行编码，因此，decrypt 命令在解密 Base64 编码的输入之前使用 `--decode` 参数对其进行解码。您也可以在加密 Base64 编码的输入之前使用 `--decode` 参数对其进行解码。

  同样，该命令省略加密上下文并忽略元数据 (-`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
  ```

------

您也可以在单个命令中执行加密和解密操作，而无需使用变量。

正如前面的示例所示，`--input` 和 `--output` 参数具有 `-` 值，命令使用 `--encode` 参数对输出进行编码，并使用 `--decode` 参数对输入进行解码。

------
#### [ 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
```

------

## 使用多个主密钥
<a name="cli-example-multimaster"></a>

此示例说明如何在加密 CLI 中加密和解密数据时使用多个主密钥。 AWS 

在使用多个主密钥加密数据时，可以使用任何一个主密钥解密数据。该策略确保您始终可以解密数据，即使某个主密钥不可用。如果您要将加密的数据存储在多个中 AWS 区域，则此策略允许您在同一区域使用主密钥来解密数据。

在使用多个主密钥进行加密时，第一个主密钥起到特殊的作用。它生成用于加密数据的数据密钥。其余主密钥加密明文数据密钥。生成的[加密消息](concepts.md#message)包含加密的数据以及加密的数据密钥集合，每个主密钥具有一个加密的数据密钥。虽然数据密钥是第一个主密钥生成的，但任何主密钥都可以解密其中的一个数据密钥，这些数据密钥可用于解密数据。

**使用三个主密钥进行加密**

该示例命令使用三个包装密钥加密 `Finance.log` 文件，在三个 AWS 区域中各具有一个包装密钥。

它将加密的消息写入到 `Archive` 目录中。该命令使用没有值的 `--suffix` 参数以忽略后缀，因此，输入和输出文件名称是相同的。

该命令使用具有三个 **key** 属性的 `--wrapping-keys` 参数。您也可以在同一命令中使用多个 `--wrapping-keys` 参数。

要加密日志文件， AWS Encryption CLI 会要求列表中的第一个封装密钥生成用于加密数据的数据密钥。`$key1`然后，分别使用其他包装密钥加密相同数据密钥的明文副本。输出文件中的加密消息包含所有三个加密的数据密钥。

------
#### [ 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
```

------

该命令解密 `Finance.log` 文件的加密副本，并将其写入到 `Finance.log.clear` 目录中的 `Finance` 文件。要解密三以下加密的数据 AWS KMS keys，可以指定相同的三个 AWS KMS keys 或其中的任何子集。该示例仅指定了其中一个 AWS KMS keys。

要告知 AWS 加密 CLI 使用哪个 AWS KMS keys 来解密您的数据，请使用参数的**`--wrapping-keys`密钥**属性。使用解密时 AWS KMS keys，密**钥属性的值必须是密钥** [AR](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id-key-ARN) N。

您必须有权在 AWS KMS keys 您指定的上调用 [Decrypt API](https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.html)。有关更多信息，请参阅 [AWS KMS的身份验证和访问控制](https://docs.aws.amazon.com/kms/latest/developerguide/control-access.html)。

作为最佳实践，该示例使用 `--max-encrypted-data-keys` 参数来避免使用过多的加密数据密钥来解密格式错误的消息。尽管该示例仅使用一个包装密钥进行解密，但加密的消息有三（3）个加密的数据密钥；加密时使用的三个包装密钥各有一个。指定预期的加密数据密钥数量或合理的最大值，例如 5。如果指定的最大值小于 3，则命令将失败。有关更多信息，请参阅 [限制加密数据密钥](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
```

------

## 在脚本中加密和解密
<a name="cli-example-script"></a>

此示例说明如何在脚本中使用 AWS 加密 CLI。您可以编写仅加密和解密数据的脚本，或者编写在数据管理过程中加密或解密的脚本。

在该示例中，脚本会获取一组日志文件，压缩并加密这些文件，然后将加密的文件复制到 Amazon S3 存储桶中。该脚本分别处理每个文件，以便单独解密和展开这些文件。

在压缩并加密文件时，请务必在加密之前进行压缩。无法压缩正确加密的数据。

**警告**  
在压缩的数据包含可能被恶意攻击者控制的密钥和数据时，要格外小心。压缩的数据的最终大小可能会无意中泄露有关其内容的敏感信息。

------
#### [ 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"
                    }
                }
            }
        }
    }
}
```

------

## 使用数据密钥缓存
<a name="cli-example-caching"></a>

该示例在加密大量文件的命令中使用[数据密钥缓存](data-key-caching.md)。

默认情况下， AWS Encryption CLI（以及的其他版本 AWS Encryption SDK）会为其加密的每个文件生成一个唯一的数据密钥。虽然在每个操作中使用唯一的数据密钥是加密最佳实践，但在某些情况下将数据密钥重用有限次数是可以接受的。如果考虑使用数据密钥缓存，请咨询安全工程师以了解您的应用程序的安全要求，并确定适合您的安全阈值。

在该示例中，数据密钥缓存降低发送到主密钥提供程序的请求频率以加快加密操作速度。

该示例中的命令加密一个具有多个子目录的大型目录，其中总共包含大约 800 个小日志文件。第一个命令将 AWS KMS key 的 ARN 保存在 `keyARN` 变量中。第二个命令加密输入目录中的所有文件（以递归方式），并将这些文件写入到存档目录中。该命令使用 `--suffix` 参数指定 `.archive` 后缀。

`--caching` 参数启用数据密钥缓存。**capacity** 属性（限制缓存中的数据密钥数）设置为 1，因为串行文件处理每次从不使用超过一个数据密钥。**max\$1age** 属性（确定可使用缓存的数据密钥的时间长度）设置为 10 秒。

可选的 **max\$1messages\$1encrypted** 属性设置为 10 个消息，因此，从不使用单个数据密钥加密超过 10 个文件。通过限制每个数据密钥加密的文件数，可以减少在极少数情况下数据密钥泄露而受到影响的文件数。

要对操作系统生成的日志文件运行该命令，您可能需要具有管理员权限（Linux 中的 `sudo`；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
```

------

为了测试数据密钥缓存的效果，此示例在中使用了 Measu [re-Command cmdlet](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/measure-command)。 PowerShell如果运行该示例而不使用数据密钥缓存，大约需要 25 秒的时间才能完成。该过程为目录中的每个文件生成新的数据密钥。

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

数据密钥缓存可以加快该过程的速度，即使将每个数据密钥限制为最多用于 10 个文件。该命令现在需要不到 12 秒的时间即可完成，并将对主密钥提供程序的调用次数减少到原来的 1/10。

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

如果消除 `max_messages_encrypted` 限制，则使用同一数据密钥加密所有文件。该更改增加了重用数据密钥的风险，而不会显著加快该过程的速度。不过，它将对主密钥提供程序的调用次数减少到 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 语法和参数参考
<a name="crypto-cli-reference"></a>

本主题提供了语法图表和简要参数描述以帮助您使用 AWS Encryption SDK 命令行界面 (CLI)。有关包装密钥和其他参数的帮助，请参阅 [如何使用 AWS 加密 CLI](crypto-cli-how-to.md)。有关示例，请参阅 [AWS 加密 CLI 的示例](crypto-cli-examples.md)。有关完整文档，请参阅[阅读文档](https://aws-encryption-sdk-cli.readthedocs.io/en/latest/)。

**Topics**
+ [

## AWS 加密 CLI 语法
](#crypto-cli-syntax)
+ [

## AWS 加密 CLI 命令行参数
](#crypto-cli-parameters)
+ [

## 高级参数
](#cli-advanced-parameters)

## AWS 加密 CLI 语法
<a name="crypto-cli-syntax"></a>

这些 AWS 加密 CLI 语法图显示了您使用 AWS 加密 CLI 执行的每项任务的语法。它们代表 AWS 加密 CLI 版本 2.1 中的推荐语法。 *x* 及更高版本。

新的安全功能最初是在 AWS 加密 CLI 版本 1.7 中发布的。 *x* 和 2.0。 *x*。但是， AWS 加密 CLI 版本为 1.8。 *x* 取代了 1.7 版。 *x* 和 AWS 加密 CLI 2.1。 *x* 取代 2.0。 *x*。有关详细信息，请参阅[aws-encryption-sdk-cli](https://github.com/aws/aws-encryption-sdk-cli/)存储库中的相关[安全公告](https://github.com/aws/aws-encryption-sdk-cli/security/advisories/GHSA-2xwp-m7mq-7q3r) GitHub。

**注意**  
除非在参数描述中注明，否则每个参数或属性只能在每个命令中使用一次。  
如果您使用参数不支持的属性，Encryption CL AWS I 会忽略该不支持的属性，而不会出现警告或错误。

**获取帮助**  
要获取包含参数描述的完整 AWS 加密 CLI 语法，请使用`--help`或`-h`。  

```
aws-encryption-cli (--help | -h)
```

**获取版本**  
要获取 AWS 加密 CLI 安装的版本号，请使用`--version`。在提问、报告问题或分享有关使用 Encryption CLI 的提示时，请务必 AWS 包含该版本。  

```
aws-encryption-cli --version
```

**加密数据**  
以下语法图表显示 **encrypt** 命令使用的参数。  

```
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** 命令使用的参数。  
在版本 1.8.*x* 中，`--wrapping-keys` 参数在解密时是可选的，但建议使用。从版本 2.1.*x* 开始，加密和解密时需要使用 `--wrapping-keys` 参数。对于 AWS KMS keys，您可以使用 **key** 属性来指定包装密钥（最佳实践），也可以将 **discovery** 属性设置为 `true`，这不会限制 AWS Encryption CLI 可以使用的包装密钥。  

```
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]
```

**使用配置文件**  
您可以引用包含参数及其值的配置文件。这相当于在命令中键入参数和值。有关示例，请参阅[如何在配置文件中存储参数](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 加密 CLI 命令行参数
<a name="crypto-cli-parameters"></a>

此列表提供了 AWS 加密 CLI 命令参数的基本描述。有关完整说明，请参阅[aws-encryption-sdk-cli文档](http://aws-encryption-sdk-cli.readthedocs.io/en/latest/)。

**--encrypt (-e)**  
加密输入数据。每个命令必须具有一个 `--encrypt` 或 `--decrypt` 或 `--decrypt-unsigned` 参数。

**--decrypt (-d)**  
解密输入数据。每个命令必须具有一个 `--encrypt`、`--decrypt` 或 `--decrypt-unsigned` 参数。

**--decrypt-unsigned [在版本 1.9.*x* 和 2.2.*x* 中引入。]**  
`--decrypt-unsigned` 参数对加密文字进行解密并确保消息在解密之前未签名。如果您使用 `--algorithm` 参数并选择了不带数字签名的算法套件来加密数据，请使用此参数。如果加密文字已签名，则解密失败。  
您可以使用 `--decrypt` 或 `--decrypt-unsigned` 进行解密，但不能同时使用两者。

**--wrapping-keys (-w) [在版本 1.8.*x* 中引入。]**  <a name="wrapping-keys"></a>
指定在加密和解密操作中使用的[包装密钥](concepts.md#master-key)（或*主密钥*）。您可以在每个命令中使用[多个 `--wrapping-keys` 参数](crypto-cli-how-to.md#cli-many-cmks)。  
从版本 2.1.*x* 开始，在加密和解密命令中需要使用 `--wrapping-keys` 参数。在版本 1.8.*x* 中，加密命令需要 `--wrapping-keys` 或 `--master-keys` 参数。在版本 1.8.*x* 解密命令中，`--wrapping-keys` 参数是可选的，但建议使用。  
使用自定义主密钥提供程序时，加密和解密命令需要使用 **key** 和 **provider** 属性。使用时 AWS KMS keys，加密命令需要密**钥**属性。解密命令需要使用 **key** 属性或值为 `true` 的 **discovery** 属性（但不能两者同时使用）。解密时使用 **key** 属性是 [AWS Encryption SDK 最佳实践](best-practices.md)。如果您要解密多批陌生消息，例如 Amazon S3 存储桶或 Amazon SQS 队列中的消息，这一点尤其重要。  
有关展示如何使用 AWS KMS 多区域密钥作为包装密钥的示例，请参阅[使用多区域 AWS KMS keys](configure.md#config-mrks)。  
**属性**：`--wrapping-keys` 参数值包含以下属性。格式为 `attribute_name=value`。    
**键**  
标识操作中使用的包装密钥。格式为 **key**=ID 对。您可以在每个 `--wrapping-keys` 参数值中指定多个 **key** 属性。  
+ **加密命令**：所有加密命令都需要使用 **key** 属性。在加密命令 AWS KMS key 中使用时，**密钥**属性的值可以是密钥 ID、密钥 ARN、别名或别名 ARN。有关 AWS KMS 密钥标识符的描述，请参阅《*AWS Key Management Service 开发人员指南*》中的[密钥标识符](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id)。
+ **解密命令**：使用 AWS KMS keys解密时，`--wrapping-keys` 参数需要使用值为[密钥 ARN](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id-key-ARN) 的 **key** 属性或值为 `true` 的 **discovery** 属性（但不能两者同时使用）。使用 **key** 属性是 [AWS Encryption SDK 最佳实践](best-practices.md)。使用自定义主密钥提供程序解密时，需要使用 **key** 属性。
**注意**  
要在解密命令中指定 AWS KMS 包装密钥，密**钥属性的值必须是密钥** ARN。如果您使用密钥 ID、别名或别名 ARN，则加密 AWS CLI 无法识别包装密钥。
您可以在每个 `--wrapping-keys` 参数值中指定多个 **key** 属性。不过，`--wrapping-keys` 参数中的任何 **provider**、**region** 和 **profile** 属性适用于该参数值中的所有包装密钥。要指定具有不同属性值的包装密钥，请在命令中使用多个 `--wrapping-keys` 参数。  
**discovery**  
允许 AWS 加密 CLI 使用任何 AWS KMS key 方法来解密邮件。**discovery** 值可以是 `true` 或 `false`。默认值为 `false`。**discovery** 属性仅在加密命令中有效，并且仅在主密钥提供程序为 AWS KMS时有效。  
使用解密时 AWS KMS keys，`--wrapping-keys`参数需要密**钥**属性或值为`true`（但不能两者兼而有之）的**发现**属性。如果您使用 **key** 属性，则可以使用值为 `false` 的 **discovery** 属性来明确拒绝发现。  
+ `False`（默认）— 当未指定**发现**属性或其值为时`false`，Encryption CLI 仅使用参数的密**钥**属性 AWS KMS keys 指定的内容来解密消息。 AWS `--wrapping-keys`如果在 discovery 为 `false` 时没有指定 **key** 属性，则解密命令将失败。此值支持加 AWS 密 CLI [最佳实践](best-practices.md)。
+ `True`— 当**发现**属性的值为时`true`， AWS Encryption CLI 会 AWS KMS keys 从加密邮件中的元数据中获取，并使用这些元数据 AWS KMS keys 来解密邮件。值为的**发现**属性的`true`行为类似于 1.8 版之前的 AWS 加密 CLI 版本。 *x* 不允许您在解密时指定包装密钥。但是，您使用 any 的意图 AWS KMS key 是明确的。如果在 discovery 为 `true` 时指定了 **key** 属性，则解密命令将失败。

  该`true`值可能会导致 Encryption CLI AWS KMS keys 在不同的 AWS 账户 区域中使用 AWS KMS keys ，或者尝试使用用户无权使用的 AWS 加密 CLI。
当**发现为发现**时`true`，最佳做法是使用**发现分区和**发现账户**属性将使用限制在您 AWS KMS keys 指定的范围**内。 AWS 账户   
**discovery-account**  
将 AWS KMS keys 用于解密的限制为指定的。 AWS 账户此属性的唯一有效值是 [AWS 账户 ID](https://docs.aws.amazon.com/general/latest/gr/acct-identifiers.html)。  
此属性是可选的，仅在**发现属性设置为且 AWS KMS keys 指定了发现****分区**属性的解密命令中有效。`true`  
每个**发现账户**属性只需要一个 AWS 账户 ID，但你可以在同一个参数中指定多个**发现账户**属性。`--wrapping-keys`在给定的 `--wrapping-keys` 参数中指定的所有账户都必须位于指定的 AWS 分区中。  
**discovery-partition**  
在 d **iscovery-account 属性中为账户**指定 AWS 分区。它的值必须是 AWS 分区，例如`aws``aws-cn`、或`aws-gov-cloud`。有关更多信息，请参阅《AWS 一般参考》** 中的 [Amazon 资源名称](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html#arns-syntax)。  
当您使用 **discovery-account** 属性时，需要使用此属性。每个 `--wrapping keys` 参数中只能指定一个 **discovery-partition** 属性。要 AWS 账户 在多个分区中指定，请使用其他`--wrapping-keys`参数。  
**提供商**  
指定[主密钥提供程序](concepts.md#master-key-provider)。格式为 **provider**=ID 对。默认值 **aws-kms 表示**。 AWS KMS只有当主密钥提供者不要求时，才需要此属性 AWS KMS。  
**region**  
标 AWS 区域 识一个 AWS KMS key。此属性仅对有效 AWS KMS keys。只有在**密钥**标识符未指定区域时，才会使用该属性，否则，将忽略该属性。使用它时，它会覆盖 AWS CLI 中名为 profile 的默认区域。  
**配置文件**  
标识已 AWS CLI [命名的配置文件](https://docs.aws.amazon.com/cli/latest/userguide/cli-multiple-profiles.html)。此属性仅对有效 AWS KMS keys。只有在密钥标识符未指定区域并且在命令中不包含 **region** 属性时，才会使用配置文件中的区域。

**--input (-i)**  
指定要加密或解密的数据的位置。此参数为必需参数。该值可以是文件或目录的路径，也可以是文件名模式。如果通过管道将输入发送到命令 (stdin)，请使用 `-`。  
如果输入不存在，该命令将成功完成，而不会显示错误或警告。    
**--recursive (-r, -R)**  
对输入目录及其子目录中的文件执行操作。在 `--input` 值为目录时，需要使用该参数。  
**--decode**  
解码 Base64 编码的输入。  
如果要解密已加密并随后编码的消息，您必须在解密该消息之前对其进行解码。该参数为您执行此操作。  
例如，如果在 encrypt 命令中使用 `--encode` 参数，请在相应的 decrypt 命令中使用 `--decode` 参数。您也可以在加密 Base64 编码的输入之前使用该参数对其进行解码。

**--output (-o)**  
指定输出的目标。此参数为必需参数。该值可以是文件名、现有目录或 `-`，后者将输出写入到命令行 (stdout)。  
如果指定的输出目录不存在，该命令将失败。如果输入包含子目录，则 AWS 加密 CLI 会在您指定的输出目录下重现子目录。  
默认情况下， AWS 加密 CLI 会覆盖同名文件。要更改该行为，请使用 `--interactive` 或 `--no-overwrite` 参数。要禁止显示覆盖警告，请使用 `--quiet` 参数。  
如果覆盖输出文件的命令失败，则会删除输出文件。  
**--interactive**  
在覆盖文件之前提示。  
**--no-overwrite**  
不覆盖文件。相反，如果输出文件存在，则 AWS 加密 CLI 会跳过相应的输入。  
**--suffix**  
为 AWS 加密 CLI 创建的文件指定自定义文件名后缀。要指示没有后缀，请使用没有值的参数 (`--suffix`)。  
默认情况下，在 `--output` 参数未指定文件名时，输出文件名与输入文件名相同并加上后缀。encrypt 命令的后缀为 `.encrypted`。decrypt 命令的后缀为 `.decrypted`。  
**--encode**  
将 Base64（二进制到文本）编码应用于输出。编码可以防止 shell 主机程序错误地解释输出文本中的非 ASCII 字符。  
在将加密输出写入 stdout (`--output -`) 时使用此参数，尤其是在 PowerShell 控制台中，即使您将输出通过管道传输到另一个命令或将其保存在变量中。

**--metadata-output**  
指定有关加密操作的元数据的位置。请输入路径和文件名。如果目录不存在，该命令将失败。要将元数据写入到命令行 (stdout) 中，请使用 `-`。  
您无法在同一命令中将命令输出 (`--output`) 和元数据输出 (`--metadata-output`) 写入到 stdout。此外，如果 `--input` 或 `--output` 值为目录（没有文件名），您无法将元数据输出写入到同一目录或该目录的任何子目录中。  
如果您指定现有文件，默认情况下，Encrypt AWS ion CLI 会将新的元数据记录附加到文件中的任何内容。通过使用该功能，您可以创建一个包含所有加密操作的元数据的文件。要覆盖现有文件中的内容，请使用 `--overwrite-metadata` 参数。  
 AWS 加密 CLI 会为该命令执行的每个加密或解密操作返回 JSON 格式的元数据记录。每个元数据记录包含输入和输出文件的完整路径、加密上下文、算法套件以及其他有价值的信息，您可以使用这些信息查看操作并验证它是否符合您的安全标准。    
**--overwrite-metadata**  
覆盖元数据输出文件中的内容。默认情况下，`--metadata-output` 参数将元数据附加到文件中的任何现有内容后面。

**--suppress-metadata (-S)**  
禁止显示有关加密或解密操作的元数据。

**--commitment-policy**  <a name="syntax-commitment-policy"></a>
指定加密和解密命令的[承诺策略](concepts.md#commitment-policy)。承诺策略决定您的消息是否使用[密钥承诺](concepts.md#key-commitment)安全功能进行加密和解密。  
`--commitment-policy` 参数在版本 1.8.*x* 中引入。该参数在加密和解密命令中有效。  
**在 1.8 版本中。 ***x*， AWS 加密 CLI 对所有加密和解密操作使用`forbid-encrypt-allow-decrypt`承诺策略。当您在加密或解密命令中使用 `--wrapping-keys` 参数时，需要使用具有 `forbid-encrypt-allow-decrypt` 值的 `--commitment-policy` 参数。如果您不使用 `--wrapping-keys` 参数，则 `--commitment-policy` 参数无效。明确设置承诺策略可防止您的承诺策略在升级到版本 2.1.*x* 时自动更改为 `require-encrypt-require-decrypt`  
从**版本 2.1.*x*** 开始，支持所有承诺策略值。`--commitment-policy` 参数是可选的，默认值为 `require-encrypt-require-decrypt`。  
此参数具有以下值：  
+ `forbid-encrypt-allow-decrypt` – 无法使用密钥承诺进行加密。可以解密使用或不使用密钥承诺加密的加密文字。

  在版本 1.8.*x* 中，这是唯一的有效值。加 AWS 密 CLI 对所有加密和解密操作使用`forbid-encrypt-allow-decrypt`承诺策略。
+ `require-encrypt-allow-decrypt` – 仅使用密钥承诺进行加密。使用和不使用密钥承诺进行解密。此值在版本 2.1.*x* 中引入。
+ `require-encrypt-require-decrypt`（默认）– 仅使用密钥承诺进行加密和解密。此值在版本 2.1.*x* 中引入。在版本 2.1.*x* 和更高版本中，这是默认值。使用此值，Encryption CLI 将不会解密使用早期版本加密的任何密文。 AWS AWS Encryption SDK
有关设置承诺策略的详细信息，请参阅 [迁移你的 AWS Encryption SDK](migration.md)。

**--encryption-context (-c)**  
为操作指定[加密上下文](crypto-cli-how-to.md#crypto-cli-encryption-context)。该参数不是必需的，但建议使用。  
+ 在 `--encrypt` 命令中，输入一个或多个 `name=value` 对。请使用空格分隔这些对。
+ 在 `--decrypt` 命令中，输入 `name=value` 对和/或没有值的 `name` 元素。
如果 `name` 对中的 `value` 或 `name=value` 包含空格或特殊字符，请将整个对用引号引起来。例如 `--encryption-context "department=software development"`。

**--buffer (-b) [在版本 1.9.*x* 和 2.2.*x* 中引入。]**  
仅在处理完所有输入之后返回明文，包括验证数字签名（如果存在）。

**--max-encrypted-data-keys [在 1.9 版本中引入。 *x* 和 2.2。 *x*]**  
指定加密消息中加密数据密钥的最大数量。此参数为可选的。  
有效值为 1-65535。如果省略此参数，则 AWS 加密 CLI 不会强制执行任何最大值。加密消息最多可以容纳 65535（2^16-1）个加密数据密钥。  
您可以在加密命令中使用此参数来防止出现格式错误的消息。您可以在解密命令中使用该参数检测恶意消息，并避免使用大量无法解密的加密数据密钥解密消息。有关详细信息和示例，请参阅[限制加密数据密钥](configure.md#config-limit-keys)。

**--help (-h)**  
在命令行中输出用法和语法。

**--version**  
获取加 AWS 密 CLI 的版本。

**-v \$1 -vv \$1 -vvv \$1 -vvvv**  
显示详细信息、警告和调试消息。输出中的详细信息随参数中的 `v` 数量而增加。最详细的设置 (`-vvvv`) 返回来自加密 AWS CLI 及其使用的所有组件的调试级数据。

**--quiet (-q)**  
禁止显示警告消息，例如，在覆盖输出文件时显示的消息。

**--master-keys (-m) [已弃用]**  
--master-keys 参数在版本 1.8.*x* 中弃用并在版本 2.1.*x* 中删除。请改用 [--wrapping-keys](#wrapping-keys) 参数。
指定在加密和解密操作中使用的[主密钥](concepts.md#master-key)。您可以在每个命令中使用多个主密钥参数。  
需要在 encrypt 命令中使用 `--master-keys` 参数。只有在使用自定义（非AWS KMS）主密钥提供程序时，才需要在解密命令中使用该参数。  
**属性**：`--master-keys` 参数值包含以下属性。格式为 `attribute_name=value`。    
**键**  
标识操作中使用的[包装密钥](concepts.md#master-key)。格式为 **key**=ID 对。需要在所有 encrypt 命令中使用 **key** 属性。  
在加密命令 AWS KMS key 中使用时，**密钥**属性的值可以是密钥 ID、密钥 ARN、别名或别名 ARN。有关 AWS KMS 密钥标识符的详细信息，请参阅《*AWS Key Management Service 开发者指南*》中的[密钥标识符](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id)。  
在主密钥提供程序不是 AWS KMS时，需要在解密命令中使用 **key** 属性。在解密根据 AWS KMS key加密的数据的命令中，不允许使用 **key** 属性。  
您可以在每个 `--master-keys` 参数值中指定多个 **key** 属性。不过，任何 **provider**、**region** 和 **profile** 属性适用于该参数值中的所有主密钥。要指定具有不同属性值的主密钥，请在命令中使用多个 `--master-keys` 参数。  
**提供商**  
指定[主密钥提供程序](concepts.md#master-key-provider)。格式为 **provider**=ID 对。默认值 **aws-kms 表示**。 AWS KMS只有当主密钥提供者不要求时，才需要此属性 AWS KMS。  
**region**  
标 AWS 区域 识一个 AWS KMS key。此属性仅对有效 AWS KMS keys。只有在**密钥**标识符未指定区域时，才会使用该属性，否则，将忽略该属性。使用它时，它会覆盖 AWS CLI 中名为 profile 的默认区域。  
**配置文件**  
标识已 AWS CLI [命名的配置文件](https://docs.aws.amazon.com/cli/latest/userguide/cli-multiple-profiles.html)。此属性仅对有效 AWS KMS keys。只有在密钥标识符未指定区域并且在命令中不包含 **region** 属性时，才会使用配置文件中的区域。

## 高级参数
<a name="cli-advanced-parameters"></a>

**--algorithm**  
指定备用的[算法套件](concepts.md#crypto-algorithm)。该参数是可选的，仅在 encrypt 命令中有效。  
如果省略此参数，则 AWS 加密 CLI 将使用 1.8 版中 AWS Encryption SDK 引入的默认算法套件之一。 *x*。两种默认算法都使用带有 [HKDF](https://en.wikipedia.org/wiki/HKDF)、ECDSA 签名和 256 位加密密钥的 AES-GCM。一种算法使用密钥承诺；一种不使用。默认算法套件的选择由命令的[承诺策略](concepts.md#commitment-policy)决定。  
建议将默认算法套件用于大多数加密操作。有关有效值的列表，请参阅 [Read the Docs](https://aws-encryption-sdk-cli.readthedocs.io/en/latest/index.html#execution) 中 `algorithm` 参数的值。

**--frame-length**  
创建具有指定帧长度的输出。该参数是可选的，仅在 encrypt 命令中有效。  
请输入一个值（字节）。有效值为 0 和 1-2^31-1。值 0 表示非帧数据。默认值为 4096（字节）。  
尽可能使用帧数据。仅 AWS Encryption SDK 支持传统使用的非成帧数据。的某些语言实现仍然 AWS Encryption SDK 可以生成非成帧的密文。所有支持的语言实现都可以解密成帧和非帧加密文字。

**--max-length**  
指示要从加密的消息中读取的最大帧大小（或非帧消息的最大内容长度），以字节为单位。该参数是可选的，仅在 decrypt 命令中有效。它旨在防止您解密非常大的恶意密文。  
请输入一个值（字节）。如果省略此参数，则解密时 AWS Encryption SDK 不会限制帧大小。

**--caching**  
启用[数据密钥缓存](data-key-caching.md)功能，该功能重用数据密钥，而不是为每个输入文件生成新的数据密钥。该参数支持高级方案。在使用该功能之前，请务必阅读[数据密钥缓存](data-key-caching.md)文档。  
`--caching` 参数具有以下属性。    
**capacity（必需）**  
确定缓存中的最大条目数。  
最小值为 1。没有最大值。  
**max\$1age（必需）**  
确定使用缓存条目的时间长度（秒），从将条目添加到缓存时算起。  
请输入一个大于 0 的值。没有最大值。  
**max\$1messages\$1encrypted（可选）**  
确定缓存的条目可以加密的最大消息数。  
有效值为 1-2^32。默认值为 2^32（消息）。  
**max\$1bytes\$1encrypted（可选）**  
确定缓存的条目可以加密的最大字节数。  
有效值为 0 和 1-2^63-1。默认值为 2^63-1（消息）。在使用值 0 时，您只能在加密空消息字符串时使用数据密钥缓存。

# AWS 加密 CLI 的版本
<a name="crypto-cli-versions"></a>

我们建议您使用最新版本的 AWS 加密 CLI。

**注意**  
[4.0.0 之前的 AWS 加密 CLI 版本处于该阶段。end-of-support](https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html#version-life-cycle)  
您无需更改任何代码或数据即可安全地从 AWS Encryption CLI 版本 2.1.*x* 及更高版本更新为最新版本。但是，版本 2.1.*x* 中引入了[新的安全功能](about-versions.md#version-2)，不向后兼容。从 1.7 版本更新。 *x* 或更早版本，必须先更新到最新的 1。 AWS 加密 CLI 的 *x* 版本。有关更多信息，请参阅 [迁移你的 AWS Encryption SDK](migration.md)。  
新的安全功能最初是在 AWS 加密 CLI 版本 1.7 中发布的。 *x* 和 2.0。 *x*。但是， AWS 加密 CLI 版本为 1.8。 *x* 取代了 1.7 版。 *x* 和 AWS 加密 CLI 2.1。 *x* 取代 2.0。 *x*。有关详细信息，请参阅[aws-encryption-sdk-cli](https://github.com/aws/aws-encryption-sdk-cli/)存储库中的相关[安全公告](https://github.com/aws/aws-encryption-sdk-cli/security/advisories/GHSA-2xwp-m7mq-7q3r) GitHub。

有关重要版本的信息 AWS Encryption SDK，请参见[的版本 AWS Encryption SDK](about-versions.md)。

**我使用哪个版本？**

如果您不熟悉加 AWS 密 CLI，请使用最新版本。

解密由 1.7 AWS Encryption SDK 之前版本加密的数据。 *x*，首先迁移到最新版本的 AWS 加密 CLI。在更新到 2.1.*x* 或更高版本之前，请执行[所有建议的更改](migration-guide.md)。有关更多信息，请参阅 [迁移你的 AWS Encryption SDK](migration.md)。

**了解详情**
+ 有关更改的详细信息以及迁移到这些新版本的指南，请参阅 [迁移你的 AWS Encryption SDK](migration.md)。
+ 有关新的 AWS 加密 CLI 参数和属性的描述，请参阅[AWS Encryption SDK CLI 语法和参数参考](crypto-cli-reference.md)。

以下列表描述了 1.8 版本中对 AWS 加密 CLI 的更改。 *x* 和 2.1。 *x*。

## 版本 1.8。 AWS 加密 CLI 的 *x* 项更改
<a name="cli-changes-1.7"></a>
+ 弃用 `--master-keys` 参数。请改用 `--wrapping-keys` 参数。
+ 添加 `--wrapping-keys` (`-w`) 参数。支持 `--master-keys` 参数的所有属性。还添加了以下可选属性，这些属性仅在使用 AWS KMS keys解密时才有效。
  + **discovery**
  + **discovery-partition**
  + **discovery-account**

  对于自定义主密钥提供程序，`--encrypt` 和 -`-decrypt` 命令需要使用 `--wrapping-keys` 参数或 `--master-keys` 参数（但不能两者同时使用）。此外，带的`--encrypt`命令 AWS KMS keys 需要`--wrapping-keys`参数或`--master-keys`参数（但不能两者兼而有之）。

  在带的`--decrypt`命令中 AWS KMS keys，`--wrapping-keys`参数是可选的，但建议使用，因为在 2.1 版本中它是必需的。 *x*。如果使用该参数，则必须指定 **key** 属性或值为 `true` 的 **discovery** 属性（但不能两者同时使用）。
+ 添加 `--commitment-policy` 参数。唯一有效值为 `forbid-encrypt-allow-decrypt`。`forbid-encrypt-allow-decrypt` 承诺策略用于所有加密和解密命令。

  在版本 1.8.*x* 中，当您使用 `--wrapping-keys` 参数时，需要使用值为 `forbid-encrypt-allow-decrypt` 的 `--commitment-policy` 参数。明确设置该值可防止您的[承诺策略](concepts.md#commitment-policy)在升级到版本 2.1.*x* 时自动更改为 `require-encrypt-require-decrypt`。

## 版本 2.1。 AWS 加密 CLI 的 *x* 项更改
<a name="cli-changes-2.x"></a>
+ 移除 `--master-keys` 参数。请改用 `--wrapping-keys` 参数。
+ 在所有加密和解密命令中需要使用 `--wrapping-keys` 参数。必须指定 **key** 属性或值为 `true` 的 **discovery** 属性（但不能两者同时使用）。
+ `--commitment-policy` 参数支持以下值。有关更多信息，请参阅 [设置您的承诺策略](migrate-commitment-policy.md)。
  + `forbid-encrypt-allow-decrypt`
  + `require-encrypt-allow-decrypt`
  + `require-encrypt-require decrypt`（默认值）
+ 在版本 2.1.*x* 中，`--commitment-policy` 参数是可选的。默认值为 `require-encrypt-require-decrypt`。

## 版本 1.9。 *x* 和 2.2。 AWS 加密 CLI 的 *x* 项更改
<a name="cli-changes-2.2"></a>
+ 添加 `--decrypt-unsigned` 参数。有关更多信息，请参阅 [版本 2.2.*x*](about-versions.md#version2.2.x)。
+ 添加 `--buffer` 参数。有关更多信息，请参阅 [版本 2.2.*x*](about-versions.md#version2.2.x)。
+ 添加 `--max-encrypted-data-keys` 参数。有关更多信息，请参阅 [限制加密数据密钥](configure.md#config-limit-keys)。

## 版本 3.0。 AWS 加密 CLI 的 *x* 项更改
<a name="cli-changes-v3"></a>
+ 增加了对 AWS KMS 多区域密钥的支持。有关详细信息，请参阅[使用多区域 AWS KMS keys](configure.md#config-mrks)。