

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

# 那是什么 AWS Encryption SDK？
<a name="introduction"></a>

 AWS Encryption SDK 是一个客户端加密库，旨在让每个人都能轻松地使用行业标准和最佳实践对数据进行加密和解密。这样，您就可以专注于应用程序的核心功能，而不是如何以最佳方式加密和解密数据。在 AWS Encryption SDK Apache 2.0 许可证下免费提供。

这些 AWS Encryption SDK 答案将为你解答如下问题：
+ 我应该使用哪种加密算法？
+ 我应该如何使用该算法或在哪种模式下使用？
+ 我如何生成加密密钥？
+ 我如何保护加密密钥，以及将其存储在什么位置？
+ 我如何使加密的数据具有便携性？
+ 我如何确保目标接收者可以读取我的加密数据？
+ 我如何确保在写入和读取我的加密数据之间不会修改这些数据？
+ 如何使用 AWS KMS 返回的数据密钥？

使用 AWS Encryption SDK，您可以定义[主密钥提供程序](concepts.md#master-key-provider)或密[钥环](concepts.md#keyring)，用于确定使用哪些封装密钥来保护数据。然后，您可以使用提供的简单方法对数据进行加密和解密。 AWS Encryption SDK剩下的 AWS Encryption SDK 就交给了。

如果没有 AWS Encryption SDK，您可能要花更多的精力来构建加密解决方案，而不是花在应用程序的核心功能上。他们通过提供以下内容来 AWS Encryption SDK 回答这些问题。

**遵循加密最佳实践的默认实施**  
默认情况下，会为其加密的每个数据对象 AWS Encryption SDK 生成一个唯一的数据密钥。这遵循在每个加密操作中使用唯一数据密钥的加密最佳实践。  
使用安全、经过身份验证的对称密钥算法对您的数据进行 AWS Encryption SDK 加密。有关更多信息，请参阅 [中支持的算法套件 AWS Encryption SDK](supported-algorithms.md)。

**使用包装密钥保护数据密钥的框架**  
通过在一个或多个封装密钥下加密数据密钥来 AWS Encryption SDK 保护加密您的数据密钥。通过提供一个使用多个包装密钥加密数据密钥的框架， AWS Encryption SDK 这有助于使您的加密数据具有可移植性。  
例如，对来自本地 HSM AWS KMS key 的 AWS KMS 输入和密钥下的数据进行加密。为了避免其中一个密钥不可用或调用方无权使用这两个密钥，您可以使用其中一个包装密钥解密数据。

**采用某种格式的消息，它存储加密的数据密钥以及加密的数据**  
将加密的数据和加密的数据密钥一起 AWS Encryption SDK 存储在使用定义数据格式的[加密消息](concepts.md#message)中。这意味着您无需跟踪或保护加密数据的数据密钥，因为这些密钥是为你 AWS Encryption SDK 做的。

的某些语言实现 AWS Encryption SDK 需要 S AWS DK，但 AWS Encryption SDK 不需要 SDK AWS 账户 ，也不依赖于任何 AWS 服务。 AWS 账户 只有当您选择使用来保护您的数据时 [AWS KMS keys](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#kms-keys)，才需要一个。

## 在开源存储库中开发
<a name="esdk-repos"></a>

 AWS Encryption SDK 是在上的开源存储库中开发的 GitHub。您可以使用这些存储库查看代码、阅读和提交问题，并且查找特定于您的语言实施的信息。
+ AWS Encryption SDK for C — [aws-encryption-sdk-c](https://github.com/aws/aws-encryption-sdk-c/)
+ AWS Encryption SDK 用于.NE [T-`aws-encryption-sdk` 存储库的.NET](https://github.com/aws/aws-encryption-sdk/tree/mainline/AwsEncryptionSDK/runtimes/net/) 目录。
+ AWS 加密 CLI — [aws-encryption-sdk-cli](https://github.com/aws/aws-encryption-sdk-cli/)
+ AWS Encryption SDK for Java — [aws-encryption-sdk-java](https://github.com/aws/aws-encryption-sdk-java/)
+ AWS Encryption SDK for JavaScript — [aws-encryption-sdk-javascript](https://github.com/aws/aws-encryption-sdk-javascript/)
+ AWS Encryption SDK for Python — [aws-encryption-sdk-python](https://github.com/aws/aws-encryption-sdk-python/)
+ AWS Encryption SDK 对于 Rus [t — `aws-encryption-sdk` 存储库的 Rust](https://github.com/aws/aws-encryption-sdk-dafny/tree/mainline/AwsEncryptionSDK/runtimes/rust/) 目录。
+ AWS Encryption SDK for G [o — `aws-encryption-sdk` 存储库的 Go](https://github.com/aws/aws-encryption-sdk/tree/mainline/releases/go/encryption-sdk/) 目录

## 与加密库和服务的兼容性
<a name="intro-compatibility"></a>

 AWS Encryption SDK 有几种[编程语言](programming-languages.md)支持。所有语言实施都是可互操作的。您可以使用一种语言实施进行加密，并使用另一种语言实施进行解密。互操作性可能受到语言约束的限制。如果是这样，这些约束将在有关语言实施的主题中进行描述。此外，在加密和解密时，必须使用兼容的密钥环或主密钥和主密钥提供程序。有关更多信息，请参阅 [密钥环兼容性](choose-keyring.md#keyring-compatibility)。

但是， AWS Encryption SDK 无法与其他库互操作。由于每个库以不同的格式返回加密的数据，因此，您无法使用一个库进行加密并使用另一个库进行解密。

**DynamoDB 加密客户端和 Amazon S3 客户端加密**  <a name="ESDK-DDBEC"></a>
 AWS Encryption SDK [无法解密由 DynamoDB 加密[客户端或 Amazon S3 客户端](https://docs.aws.amazon.com/dynamodb-encryption-client/latest/devguide/)加密加密的数据。](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingClientSideEncryption.html)这些库无法解密返回的[加密消息](concepts.md#message)。 AWS Encryption SDK  

**AWS Key Management Service (AWS KMS)**  <a name="ESDK-KMS"></a>
 AWS Encryption SDK 可以使用的[AWS KMS keys](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys)和[数据密钥](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#data-keys)来保护您的数据，包括多区域 KMS 密钥。例如，您可以将配置 AWS Encryption SDK 为在 AWS KMS keys 中的一个或多个下加密您的数据 AWS 账户。但是，您必须使用 AWS Encryption SDK 来解密该数据。  
 AWS Encryption SDK 无法解密 AWS KMS [加密](https://docs.aws.amazon.com/kms/latest/APIReference/API_Encrypt.html)或操作返回的密文。[ReEncrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_ReEncrypt.html)同样， AWS KMS [解密](https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.html)操作无法解密返回的[加密](concepts.md#message)消息。 AWS Encryption SDK   
仅 AWS Encryption SDK 支持对[称加密 KMS 密钥](https://docs.aws.amazon.com/kms/latest/developerguide/symm-asymm-concepts.html#symmetric-cmks)。您无法使用[非对称 KMS 密钥](https://docs.aws.amazon.com/kms/latest/developerguide/symm-asymm-concepts.html#asymmetric-cmks)在 AWS Encryption SDK中进行加密或签名。 AWS Encryption SDK 为对消息进行签名的[算法套件](supported-algorithms.md)生成自己的 ECDSA 签名密钥。

## 支持和维护
<a name="support"></a>

 AWS Encryption SDK 使用与 AWS SDK 和工具相同的[维护策略](https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html)，包括其版本控制和生命周期阶段。作为[最佳实践](best-practices.md)，我们建议您使用 AWS Encryption SDK 适用于您的编程语言的最新可用版本，并在新版本发布时进行升级。当版本需要进行重大更改时，例如从 1.7 之前的 AWS Encryption SDK 版本升级。 *x* 到 2.0 版本。 *x* 及以后，我们会提供[详细的说明](migration.md)来帮助您。

的每种编程语言实现都 AWS Encryption SDK 是在单独的开源 GitHub 存储库中开发的。每个版本的生命周期和支持阶段可能因存储库而异。例如，给定版本的在一种编程语言中 AWS Encryption SDK 可能处于正式发布（完全支持）阶段，但处于另一种编程语言的 end-of-support阶段。我们建议您尽可能使用全面支持的版本，避免使用不再受支持的版本。

要查找您的编程语言 AWS Encryption SDK 版本的生命周期阶段，请查看每个 AWS Encryption SDK 存储库中的`SUPPORT_POLICY.rst`文件。
+ AWS Encryption SDK for C — s [upport\$1policy.r](https://github.com/aws/aws-encryption-sdk-c/blob/master/SUPPORT_POLICY.rst)
+ AWS Encryption SDK 适用于.NET — s [upp](https://github.com/aws/aws-encryption-sdk-dafny/blob/mainline/SUPPORT_POLICY.rst) ort\$1policy.
+ AWS 加密 CLI — s [upport\$1policy.r](https://github.com/aws/aws-encryption-sdk-cli/blob/master/SUPPORT_POLICY.rst) s
+ AWS Encryption SDK for Java — s [upport\$1policy.r](https://github.com/aws/aws-encryption-sdk-java/blob/master/SUPPORT_POLICY.rst)
+ AWS Encryption SDK for JavaScript — s [upport\$1policy.r](https://github.com/aws/aws-encryption-sdk-javascript/blob/master/SUPPORT_POLICY.rst)
+ AWS Encryption SDK for Python — s [upport\$1policy.r](https://github.com/aws/aws-encryption-sdk-python/blob/master/SUPPORT_POLICY.rst)

有关更多信息，请参阅[的版本 AWS Encryption SDK](about-versions.md)[AWS SDKs 和工具参考指南中的 AWS SDKs 和和和工具维护政策](https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html)。

## 了解更多信息
<a name="intro-see-also"></a>

有关 AWS Encryption SDK 和客户端加密的更多信息，请尝试以下来源。
+ 有关该开发工具包中使用的术语和概念的帮助，请参阅[中的概念 AWS Encryption SDK](concepts.md)。
+ 有关最佳实践准则，请参阅 [的最佳实践 AWS Encryption SDK](best-practices.md)。
+ 有关该开发工具包的工作方式的信息，请参阅[该开发工具包的工作方式](how-it-works.md)。
+ 有关展示如何在中配置选项的示例 AWS Encryption SDK，请参阅[正在配置 AWS Encryption SDK](configure.md)。
+ 有关详细的技术信息，请参阅[AWS Encryption SDK 参考](reference.md)。
+ 有关的技术规格 AWS Encryption SDK，请参阅中的[AWS Encryption SDK 规范](https://github.com/awslabs/aws-encryption-sdk-specification/) GitHub。
+ 有关使用问题的答案 AWS Encryption SDK，请阅读[AWS 加密工具讨论论坛](https://forums.aws.amazon.com/forum.jspa?forumID=302)并发帖。

有关 AWS Encryption SDK 在不同编程语言中实现的信息。
+ **C**: [AWS Encryption SDK for C](c-language.md) 请参阅 AWS Encryption SDK [C 文档](https://aws.github.io/aws-encryption-sdk-c/html/)和上的[aws-encryption-sdk-c](https://github.com/aws/aws-encryption-sdk-c/)存储库 GitHub。
+ **C\$1/.NET**：参见[AWS Encryption SDK 对于.NET](dot-net.md)，存储库的[aws-encryption-sdk-net](https://github.com/aws/aws-encryption-sdk/tree/mainline/AwsEncryptionSDK/runtimes/net/)`aws-encryption-sdk`目录已打开。 GitHub
+ **命令行界面**：参见[AWS Encryption SDK 命令行界面](crypto-cli.md)，[阅读 AWS 加密 CLI 的文档](https://aws-encryption-sdk-cli.readthedocs.io/en/latest/)，以及上面的[aws-encryption-sdk-cli](https://github.com/aws/aws-encryption-sdk-cli/)存储库 GitHub。
+ **Java**：参见 [AWS Encryption SDK for Java](java.md) AWS Encryption SDK [Javadoc](https://aws.github.io/aws-encryption-sdk-java/) 和上面的[aws-encryption-sdk-java](https://github.com/aws/aws-encryption-sdk-java/)存储库。 GitHub

  **JavaScript**: 请参阅[AWS Encryption SDK for JavaScript](javascript.md)，[aws-encryption-sdk-javascript](https://github.com/aws/aws-encryption-sdk-javascript/)存储库已打开 GitHub。
+ **Python**：参见 [AWS Encryption SDK for Python](python.md) AWS Encryption SDK [Python 文档](https://aws-encryption-sdk-python.readthedocs.io/en/latest/)和上[aws-encryption-sdk-python](https://github.com/aws/aws-encryption-sdk-python/)面的存储库 GitHub。

## 发送反馈
<a name="report-issues"></a>

我们欢迎您提供反馈！如果您有任何疑问或意见或者要报告问题，请使用以下资源。
+ 如果您在中发现潜在的安全漏洞 AWS Encryption SDK，请[通知 AWS 安全部门](https://aws.amazon.com/security/vulnerability-reporting/)。不要创建公开 GitHub 问题。
+ 要提供相关反馈 AWS Encryption SDK，请在 GitHub 存储库中提交您正在使用的编程语言的问题。
+ 要提供有关本文档的反馈，请使用该页面上的**反馈**链接。您也可以提交问题或为[aws-encryption-sdk-docs](https://github.com/awsdocs/aws-encryption-sdk-docs)本文档的开源存储库做出贡献 GitHub。

# 中的概念 AWS Encryption SDK
<a name="concepts"></a>

本节介绍中使用的概念 AWS Encryption SDK，并提供词汇表和参考资料。它旨在帮助您了解其 AWS Encryption SDK 工作原理以及我们用来描述它的术语。

需要帮助？ 
+ 了解如何 AWS Encryption SDK 使用[信封加密](#envelope-encryption)来保护您的数据。
+ 了解信封加密的要素：保护数据的[数据密钥](#DEK)以及保护数据密钥的[包装密钥](#master-key)。
+ 了解决定您使用哪种包装密钥的[密钥环](#keyring)和[主密钥提供程序](#master-key-provider)。
+ 了解可增强加密过程完整性的[加密上下文](#encryption-context)。这是可选的，但却是我们建议的最佳实践。
+ 了解加密方法返回的[加密消息](#message)。
+ 然后，您就可以用自己喜欢的[编程语言](programming-languages.md)使用了。 AWS Encryption SDK 

**Topics**
+ [信封加密](#envelope-encryption)
+ [数据密钥](#DEK)
+ [包装密钥](#master-key)
+ [密钥环和主密钥提供程序](#keyring)
+ [加密上下文](#encryption-context)
+ [加密的消息](#message)
+ [算法套件](#crypto-algorithm)
+ [加密材料管理器](#crypt-materials-manager)
+ [对称和非对称加密](#symmetric-key-encryption)
+ [密钥承诺](#key-commitment)
+ [承诺策略](#commitment-policy)
+ [数字签名](#digital-sigs)

## 信封加密
<a name="envelope-encryption"></a>

加密的数据的安全性部分取决于如何保护可解密该数据的数据密钥。保护数据密钥的一种公认的最佳实践是对其进行加密。为此，您需要另一个加密密钥，称为*密钥加密密钥*或[包装密钥](#master-key)。使用包装密钥加密数据密钥的做法称为*信封加密*。

**保护数据密钥**  
使用唯一的数据 AWS Encryption SDK 密钥对每条消息进行加密。然后，对您指定的包装密钥下的数据密钥进行加密。将加密的数据密钥与加密的数据一并存储在其返回的加密消息中。  
要指定包装密钥，请使用[密钥环](#keyring)或[主密钥提供程序](#master-key-provider)。  

![\[使用信封加密 AWS Encryption SDK\]](http://docs.aws.amazon.com/zh_cn/encryption-sdk/latest/developer-guide/images/envelope-encryption-70.png)


**在多个包装密钥下加密相同的数据**  
您可以在多个包装密钥下加密数据密钥。您可能希望为不同的用户提供不同的包装密钥，或者提供不同类型的包装密钥，或者位于不同的位置。每个包装密钥都加密相同的数据密钥。将所有加密数据密钥和加密数据 AWS Encryption SDK 存储在加密消息中。  
要解密数据，您需要提供可以解密任一加密数据密钥的包装密钥。  

![\[每个包装密钥对相同的数据密钥进行加密，从而为每个包装密钥生成一个加密的数据密钥\]](http://docs.aws.amazon.com/zh_cn/encryption-sdk/latest/developer-guide/images/multiple-wrapping-keys-70.png)


**结合多种算法的优势**  
要加密您的数据，默认情况下， AWS Encryption SDK 使用具有 AES-GCM 对称加密、密钥派生函数 (HKDF) 和签名的复杂[算法套件](supported-algorithms.md)。要加密数据密钥，您可以指定适合您的包装密钥的[对称或非对称加密算法](#symmetric-key-encryption)。  
通常，与非对称或*公有密钥加密* 相比，对称密钥加密算法速度更快，生成的密文更小。但公有密钥算法可提供固有的角色分离和更轻松的密钥管理。为了结合每种算法的优势，您可以使用对称密钥加密功能加密数据，然后使用公有密钥加密功能加密数据密钥。

## 数据密钥
<a name="DEK"></a>

*数据密钥* 是 AWS Encryption SDK 用于加密数据的加密密钥。每个数据密钥都是一个符合加密密钥要求的字节数组。除非您使用[数据密钥缓存](data-key-caching.md)，否则会 AWS Encryption SDK 使用唯一的数据密钥来加密每条消息。

您无需指定、生成、实施、扩展、保护或使用数据密钥。当您调用加密和解密操作时， AWS Encryption SDK 会替您完成这些工作。

为了保护您的数据密钥，使用一个或多个密钥 AWS Encryption SDK 加密密钥（称为[包装](#master-key)密*钥或主密钥）对其进行加*密。 AWS Encryption SDK 使用您的纯文本数据密钥加密您的数据后，它会尽快将其从内存中删除。然后，它将加密的数据密钥与加密的数据一并存储在加密操作返回的[加密消息](#message)中。有关更多信息，请参阅 [AWS Encryption SDK 工作原理](how-it-works.md)。

**提示**  
在中 AWS Encryption SDK，我们将数据密钥与**数据加密*密钥*区分开来。一些支持的[算法套件](#crypto-algorithm)（包括默认套件）使用[密钥派生函数](https://en.wikipedia.org/wiki/Key_derivation_function)以防止数据密钥达到其加密限制。密钥派生函数将数据密钥作为输入，并返回实际用于加密数据的数据加密密钥。因此，我们通常说数据是“根据”数据密钥加密的，而不是“由”数据密钥加密的。

每个加密的数据密钥都包含元数据，包括对其进行加密的包装密钥的标识符。此元数据使在 AWS Encryption SDK 解密时可以更轻松地识别有效的包装密钥。

## 包装密钥
<a name="master-key"></a>

*包装密钥*是一种密钥加密密钥， AWS Encryption SDK 使用该密钥加密用于加密数据的[数据密钥](#DEK)。可以使用一个或多个包装密钥加密每个明文数据密钥。在配置[密钥环](#keyring)或[主密钥提供程序](#master-key-provider)时，您可以决定使用哪些包装密钥来保护您的数据。

**注意**  
*包装密钥*是指密钥环或主密钥提供程序中的密钥。*主密钥*通常与您在使用主密钥提供程序时实例化的 `MasterKey` 类相关联。

 AWS Encryption SDK 支持多种常用的包装密钥，例如 AWS Key Management Service (AWS KMS) 对称 [AWS KMS keys](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys)（包括[多区域 KMS 密钥](configure.md#config-mrks)）、原始 AES-GCM（高级加密 Standard/Galois 计数器模式）密钥和原始 RSA 密钥。您还可以扩展或实施自己的包装密钥。

在使用信封加密时，您需要保护包装密钥以防止未经授权的访问。您可以通过以下任何方式来执行此操作：
+ 使用专用于该用途的 Web 服务，如 [AWS Key Management Service (AWS KMS)](https://aws.amazon.com/kms/)。
+ 使用[硬件安全模块 (HSM)](https://en.wikipedia.org/wiki/Hardware_security_module)，例如，[AWS CloudHSM](https://aws.amazon.com/cloudhsm/) 提供的模块。
+ 使用其他密钥管理工具和服务。

如果您没有密钥管理系统，我们建议您使用 AWS KMS。与 AWS Encryption SDK 集成 AWS KMS ，可帮助您保护和使用包装密钥。但是， AWS Encryption SDK 不需要 AWS 或任何 AWS 服务。

## 密钥环和主密钥提供程序
<a name="keyring"></a>

要指定用于加密和解密的包装密钥，您可以使用密钥环或主密钥提供程序。您可以使用他们提供的密钥环和主密钥提供程序，也可以设计自己的实现。 AWS Encryption SDK AWS Encryption SDK 提供相互兼容的密钥环和主密钥提供程序，但须遵守语言限制。有关更多信息，请参阅 [密钥环兼容性](choose-keyring.md#keyring-compatibility)。

*密钥环* 生成、加密和解密数据密钥。定义密钥环时，可以指定用于加密数据密钥的[包装密钥](#master-key)。大多数密钥环至少指定一个包装密钥或一项提供和保护包装密钥的服务。您也可以定义不带包装密钥的密钥环，或者使用其他配置选项定义更复杂的密钥环。有关选择和使用 AWS Encryption SDK 定义的钥匙圈的帮助，请参阅[密钥环](choose-keyring.md)。

以下编程语言支持密钥环：
+ AWS Encryption SDK for C
+ AWS Encryption SDK for JavaScript
+ AWS Encryption SDK 对于.NET
+ 版本 3。 的 *x* AWS Encryption SDK for Java
+ 版本 4。 的 *x* AWS Encryption SDK for Python，与可选的[加密材料提供程序库](https://github.com/aws/aws-cryptographic-material-providers-library) (MPL) 依赖项一起使用时。
+ 版本 1。 *x 的 fo* r AWS Encryption SDK Rust
+ 版本 0.1。 *x* 或更高版本的 fo AWS Encryption SDK r Go

*主密钥提供程序*是密钥环的替代方案。主密钥提供程序返回您指定的包装密钥（或主密钥）。每个主密钥与一个主密钥提供程序相关联，但主密钥提供程序通常提供多个主密钥。Java、Python 和 AWS 加密 CLI 支持主密钥提供程序。

您必须指定用于加密的密钥环（或主密钥提供程序）。您可以指定相同的密钥环（或主密钥提供程序）或不同的密钥环进行解密。加密时， AWS Encryption SDK 使用您指定的所有包装密钥来加密数据密钥。解密时， AWS Encryption SDK 仅使用您指定的包装密钥来解密加密的数据密钥。指定用于解密的包装密钥是可选的，但这是 AWS Encryption SDK [最佳](best-practices.md)实践。

有关指定包装密钥的详细信息，请参阅 [选择包装密钥](configure.md#config-keys)。

## 加密上下文
<a name="encryption-context"></a>

为了提高加密操作安全性，请在所有加密数据的请求中包含加密上下文。使用加密上下文是可选的，但这是我们建议遵守的加密最佳实践。

*加密上下文* 是一组名称值对，其中包含任意非机密经过身份验证的附加数据。加密上下文可以包含您选择的任何数据，但它通常包含用于日志记录和跟踪的数据，例如，有关文件类型、用途或所有权的数据。当您加密数据时，加密上下文以加密方式绑定到加密的数据，以便需要使用相同的加密上下文解密数据。 AWS Encryption SDK 将加密上下文以明文形式包含在其返回的[加密的消息](#message)标头中。

 AWS Encryption SDK 使用的加密上下文包括您指定的加密上下文和[加密材料管理器](#crypt-materials-manager) (CMM) 添加的公钥对。具体来说，每当您使用[带签名的加密算法](algorithms-reference.md)时，CMM 都会向加密上下文（由保留名称、`aws-crypto-public-key` 和表示公有验证密钥的值组成）添加一个名称/值对。加密上下文中的`aws-crypto-public-key`名称由保留 AWS Encryption SDK ，不能在加密上下文中用作任何其他对中的名称。有关详细信息，请参阅“消息格式参考**”中的 [AAD](message-format.md#header-aad)。

下面的示例加密上下文由请求中指定的两个加密上下文对和 CMM 添加的公有密钥对组成。

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

要解密数据，您可以传入加密的消息。由于 AWS Encryption SDK 可以从加密的邮件标头中提取加密上下文，因此您无需单独提供加密上下文。但是，加密上下文可帮助您确认解密的是正确的加密消息。
+ 在 [AWS Encryption SDK 命令行界面](crypto-cli.md) (CLI) 中，如果您在 decrypt 命令中提供加密上下文，CLI 将在返回明文数据前验证加密消息的加密上下文中是否存在这些值。
+ 在其他编程语言实现中，解密响应包含加密上下文和明文数据。应用程序中的解密函数应始终在返回明文数据前验证解密响应中的加密上下文是否包含加密请求（或子集）中的加密上下文。

**注意**  
以下版本支持[所需的加密上下文 CMM](configure.md#config-required-encryption-context-cmm)，您可以使用它来要求在所有加密请求中使用加密上下文。  
版本 3。 的 *x* AWS Encryption SDK for Java
版本 4。 .NET 的 *x* 及更高版本 AWS Encryption SDK 
版本 4。 的 *x* AWS Encryption SDK for Python，与可选的[加密材料提供程序库](https://github.com/aws/aws-cryptographic-material-providers-library) (MPL) 依赖项一起使用时。
版本 1。 *x 的 fo* r AWS Encryption SDK Rust
版本 0.1。 *x* 或更高版本的 fo AWS Encryption SDK r Go

在选择加密上下文时，请记住它不是机密的。加密上下文以明文形式显示在 AWS Encryption SDK 返回的[加密的消息](#message)标头中。如果您使用的是 AWS Key Management Service，加密上下文也可能以纯文本形式出现在审计记录和日志中，例如。 AWS CloudTrail

有关在代码中提交和验证加密上下文的示例，请参阅您的首选[编程语言](programming-languages.md)示例。

## 加密的消息
<a name="message"></a>

当您使用加密数据时 AWS Encryption SDK，它会返回一条加密的消息。

*加密的消息*是一种可移植的[格式化数据结构](message-format.md)，包含加密的数据、数据密钥的加密副本、算法 ID 以及可选的[加密上下文](#encryption-context)和[数字签名](#digital-sigs)。 AWS Encryption SDK 中的加密操作返回加密的消息，解密操作将加密的消息作为输入。

将加密的数据及其加密的数据密钥合并在一起可以简化解密操作，您不必将加密的数据密钥独立于它们加密的数据进行存储和管理。

有关加密的消息的技术信息，请参阅[加密的消息格式](message-format.md)。

## 算法套件
<a name="crypto-algorithm"></a>

 AWS Encryption SDK 使用算法套件对加密和解密操作返回的[加密消息](#message)中的数据进行加密和签名。 AWS Encryption SDK 支持一些[算法套件](supported-algorithms.md)。所有支持的套件将高级加密标准 (AES) 作为主要算法，并将其与其他算法和值组合使用。

 AWS Encryption SDK 建立了推荐的算法套件，作为所有加密操作的默认算法套件。随着标准和最佳实践的不断改进，默认套件可能会发生变化。您可以在加密数据的请求中或在创建[加密材料管理器（CMM）](#crypt-materials-manager)时指定备用算法套件，但除非您的环境需要使用备用套件，否则，最好使用默认套件。当前的默认值是 AES-GCM，具有基于 HMAC 的 extract-and-expand[密钥派生函数](https://en.wikipedia.org/wiki/HKDF) (H [KDF](https://en.wikipedia.org/wiki/HKDF))、[密钥承诺](#key-commitment)、[椭圆曲线数字签名算法 (ECDSA) 签名](#digital-sigs)和 256 位加密密钥。

如果您的应用程序需要高性能，并且加密数据的用户和解密数据的用户同样受到信任，则可以考虑指定不带数字签名的算法套件。但是，我们强烈建议使用包含密钥承诺和密钥派生函数的算法套件。支持没有这些功能的算法套件仅为了保持向后兼容。

## 加密材料管理器
<a name="crypt-materials-manager"></a>

加密材料管理器（CMM）组装用于加密和解密数据的加密材料。*加密材料* 包含明文和加密的数据密钥以及可选的消息签名密钥。您永远不会直接与 CMM 交互。加密和解密方法替您进行处理。

您可以使用默认 CMM 或 AWS Encryption SDK 提供的[缓存 CMM](data-key-caching.md)，也可以编写自定义 CMM。您可以指定 CMM，但这不是必需的。当您指定密钥环或主密钥提供程序时， AWS Encryption SDK 会为您创建默认 CMM。默认 CMM 从您指定的密钥环或主密钥提供程序获取加密或解密材料。这可能涉及调用一个加密服务，如 [AWS Key Management Service](https://docs.aws.amazon.com/kms/latest/developerguide/) (AWS KMS)。

由于 CMM 充当 AWS Encryption SDK 与密钥环（或主密钥提供程序）之间的联络人，因此它是自定义和扩展（例如支持策略实施和缓存）的理想场所。 AWS Encryption SDK 提供了缓存 CMM 以支持[数据密钥缓存](data-key-caching.md)。

## 对称和非对称加密
<a name="symmetric-key-encryption"></a>

*对称加密*使用相同的密钥来加密和解密数据。

*非对称加密*使用数学相关的数据密钥对。密钥对中的一个密钥对数据进行加密；只有密钥对中的另一个密钥可以解密数据。

 AWS Encryption SDK 使用[信封加密](#envelope-encryption)。使用对称数据密钥加密您的数据。使用一个或多个对称或非对称包装密钥加密对称数据密钥。返回一条[加密的消息](#message)，其中包含加密数据和至少一个数据密钥的加密副本。

**加密数据（对称加密）**  
要加密您的数据， AWS Encryption SDK 使用对称[数据密钥](#DEK)和包含对称加密[算法的算法套件](#crypto-algorithm)。要解密数据， AWS Encryption SDK 使用相同的数据密钥和相同的算法套件。

**加密数据密钥（对称或非对称加密）**  
您为加密和解密操作提供的[密钥环](#keyring)或[主密钥提供程序](#master-key-provider)决定了对称数据密钥的加密和解密方式。您可以选择使用对称加密的密钥环或主密钥提供程序（例如密钥环），也可以选择使用非对称加密的 AWS KMS 密钥环或主密钥提供程序，例如原始的 RSA 密钥环或。`JceMasterKey`

## 密钥承诺
<a name="key-commitment"></a>

 AWS Encryption SDK 支持*密钥承诺*（有时称为*稳健性*），这是一种安全属性，可保证每个密文只能解密为单个纯文本。为此，密钥承诺可保证仅使用加密消息的数据密钥来解密消息。使用密钥承诺进行加密和解密是 [AWS Encryption SDK 最佳实践](best-practices.md)。

大多数现代对称密码（包括 AES）使用单个密钥对明文进行加密，例如 AWS Encryption SDK 用于加密每条明文消息的[唯一数据密钥](#DEK)。使用相同的数据密钥解密这些数据会返回与原始数据相同的明文。使用不同的密钥解密通常会失败。但是，有可能使用两个不同的密钥解密加密文字。在极少数情况下，找到一个密钥来将几个字节的加密文字解密成不同但仍然可以理解的明文是可行的。

 AWS Encryption SDK 始终使用一个唯一的数据密钥对每条纯文本消息进行加密。可能会使用多个包装密钥（或主密钥）加密该数据密钥，但包装密钥始终加密相同的数据密钥。尽管如此，手动制作的复杂[加密的消息](#message)实际上可能包含不同的数据密钥，每个数据密钥都由不同的包装密钥加密。例如，如果一个用户对加密的消息进行解密，将返回 0x0（false），而另一个用户解密相同的加密消息则得到 0x1（true）。

为防止出现这种情况， AWS Encryption SDK 支持加密和解密时的密钥承诺。当使用密钥承诺对消息 AWS Encryption SDK 进行加密时，它会以加密方式将生成密文的唯一数据密钥绑定到密钥*承诺字符串（非秘密数据密钥标识符*）。然后，将密钥承诺字符串存储在加密消息的元数据中。当它使用密钥承诺解密消息时， AWS Encryption SDK 会验证数据密钥是否是该加密消息的唯一密钥。如果数据密钥验证失败，则解密操作将失败。

在版本 1.7.*x* 中引入了对密钥承诺的支持，可以解密带有密钥承诺的消息，但不会使用密钥承诺进行加密。您可以使用此版本全面部署使用密钥承诺解密加密文字的功能。版本 2.0.*x* 包括对密钥承诺的全面支持。默认情况下，仅使用密钥承诺进行加密和解密。对于不需要解密由早期版本加密的密文的应用程序来说，这是一种理想的配置。 AWS Encryption SDK

尽管使用密钥承诺进行加密和解密是最佳实践，但我们允许您决定何时使用密钥，并允许您调整采用密钥的进度。从 1.7 版本开始。 *x*， AWS Encryption SDK 支持用于设置[默认算法套件](supported-algorithms.md)并限制可能使用的算法套件的[承诺策略](#commitment-policy)。此策略决定您的数据是否通过密钥承诺进行加密和解密。

密钥承诺会生成[稍大（30 多个字节）的加密消息](message-format.md)，并且需要更多时间来处理。如果您的应用程序对大小或性能非常敏感，则可以选择退出密钥承诺。但只有在必要时才这样做。

有关迁移到版本 1.7.*x* 和 2.0.*x* 的更多信息，包括其密钥承诺功能，请参阅 [迁移你的 AWS Encryption SDK](migration.md)。有关密钥承诺的技术信息，请参阅 [AWS Encryption SDK 算法参考](algorithms-reference.md) 和 [AWS Encryption SDK 消息格式参考](message-format.md)。

## 承诺策略
<a name="commitment-policy"></a>

*承诺策略*是一种配置设置，用于确定您的应用程序是否使用[密钥承诺](#key-commitment)进行加密和解密。使用密钥承诺进行加密和解密是 [AWS Encryption SDK 最佳实践](best-practices.md)。

承诺策略有三个值。

**注意**  
您可能需要水平或垂直滚动才能查看整个表。


**承诺策略值**  

| 值 | 使用密钥承诺进行加密 | 不使用密钥承诺进行加密 | 使用密钥承诺进行解密 | 不使用密钥承诺进行解密 | 
| --- | --- | --- | --- | --- | 
| ForbidEncryptAllowDecrypt | ![\[Red circle with white X inside, indicating prohibition or cancellation.\]](http://docs.aws.amazon.com/zh_cn/encryption-sdk/latest/developer-guide/images/icon-no.png)  | ![\[Green checkmark icon indicating approval or confirmation.\]](http://docs.aws.amazon.com/zh_cn/encryption-sdk/latest/developer-guide/images/icon-yes.png)  | ![\[Green checkmark icon indicating approval or confirmation.\]](http://docs.aws.amazon.com/zh_cn/encryption-sdk/latest/developer-guide/images/icon-yes.png) | ![\[Green checkmark icon indicating approval or confirmation.\]](http://docs.aws.amazon.com/zh_cn/encryption-sdk/latest/developer-guide/images/icon-yes.png) | 
| RequireEncryptAllowDecrypt | ![\[Green checkmark icon indicating approval or confirmation.\]](http://docs.aws.amazon.com/zh_cn/encryption-sdk/latest/developer-guide/images/icon-yes.png) | ![\[Red circle with white X inside, indicating prohibition or cancellation.\]](http://docs.aws.amazon.com/zh_cn/encryption-sdk/latest/developer-guide/images/icon-no.png) | ![\[Green checkmark icon indicating approval or confirmation.\]](http://docs.aws.amazon.com/zh_cn/encryption-sdk/latest/developer-guide/images/icon-yes.png) | ![\[Green checkmark icon indicating approval or confirmation.\]](http://docs.aws.amazon.com/zh_cn/encryption-sdk/latest/developer-guide/images/icon-yes.png) | 
| RequireEncryptRequireDecrypt | ![\[Green checkmark icon indicating approval or confirmation.\]](http://docs.aws.amazon.com/zh_cn/encryption-sdk/latest/developer-guide/images/icon-yes.png) | ![\[Red circle with white X inside, indicating prohibition or cancellation.\]](http://docs.aws.amazon.com/zh_cn/encryption-sdk/latest/developer-guide/images/icon-no.png) | ![\[Green checkmark icon indicating approval or confirmation.\]](http://docs.aws.amazon.com/zh_cn/encryption-sdk/latest/developer-guide/images/icon-yes.png) | ![\[Red circle with white X inside, indicating prohibition or cancellation.\]](http://docs.aws.amazon.com/zh_cn/encryption-sdk/latest/developer-guide/images/icon-no.png) | 

1.7 AWS Encryption SDK 版中引入了承诺策略设置。 *x*。该设置在所有支持的[编程语言](programming-languages.md)中都有效。
+ `ForbidEncryptAllowDecrypt` 使用或不使用密钥承诺进行解密，但不会使用密钥承诺进行加密。此值在 1.7 版本中引入。 *x*，旨在让所有运行您的应用程序的主机在遇到使用密钥承诺加密的密文之前准备好使用密钥承诺进行解密。
+ `RequireEncryptAllowDecrypt` 始终使用密钥承诺进行加密。可以使用或不使用密钥承诺进行解密。此值在版本 2.0.*x* 中引入，允许您使用密钥承诺开始加密，但仍然可以不使用密钥承诺解密旧加密文字。
+ `RequireEncryptRequireDecrypt` 仅使用密钥承诺进行加密和解密。此值是版本 2.0.*x* 的默认值。当您确定所有加密文字都使用密钥承诺进行加密时，请使用此值。

承诺策略设置决定了您可以使用哪些算法套件。从 1.7 版本开始。 *x*， AWS Encryption SDK 支持密钥承诺的[算法套件](supported-algorithms.md)；有签名和不带签名。如果您指定的算法套件与您的承诺策略冲突，则 AWS Encryption SDK 会返回错误。

有关设置承诺策略的帮助，请参阅 [设置您的承诺策略](migrate-commitment-policy.md)。

## 数字签名
<a name="digital-sigs"></a>

使用经过身份验证的 AWS Encryption SDK 加密算法 AES-GCM 对您的数据进行加密，解密过程无需使用数字签名即可验证加密消息的完整性和真实性。但是，由于 AES-GCM 使用对称密钥，所以能够解密用于解密加密文字的数据密钥的任何人员都可以手动创建新的加密的加密文字，从而造成潜在的安全问题。例如，如果您使用 AWS KMS key 作为包装密钥，则具有`kms:Decrypt`权限的用户无需调用即可创建加密的密文。`kms:Encrypt`

为避免此问题， AWS Encryption SDK 支持在加密消息的末尾添加椭圆曲线数字签名算法 (ECDSA) 签名。使用签名算法套件时，会为每封加密消息 AWS Encryption SDK 生成临时私钥和公钥对。将公钥 AWS Encryption SDK 存储在数据密钥的加密环境中，并丢弃私钥。这样可以确保任何人都无法创建另一个使用公钥进行验证的签名。该算法将公钥绑定到加密的数据密钥作为邮件标头中的其他经过身份验证的数据，从而防止只能解密消息的用户更改公钥或影响签名验证。

签名验证会增加大量的解密性能成本。如果加密数据的用户和解密数据的用户同样受到信任，请考虑使用不包括签名功能的算法套件。

**注意**  
如果密钥环或对封装加密材料的访问权限未在加密器和解密器之间划清界限，则数字签名不提供任何加密价值。

[AWS KMS 密钥环](use-kms-keyring.md)（包括非对称 RSA AWS KMS 密钥环）可以根据密钥策略和 IAM 策略在加密器和解密器之间进行划分。 AWS KMS 

由于其加密性质，以下密钥环无法在加密器和解密器之间进行划分：
+ AWS KMS 分层钥匙圈
+ AWS KMS ECDH 钥匙圈
+ 原始 AES 密钥环
+ 原始 RSA 密钥环
+ 未加工的 ECDH 钥匙圈

# AWS Encryption SDK 工作原理
<a name="how-it-works"></a>

[本节中的工作流程说明了如何 AWS Encryption SDK 加密数据和解密加密的消息。](concepts.md#message)这些工作流使用默认特征描述基本流程。有关定义和使用自定义组件的详细信息，请参阅每种支持的[语言实现](programming-languages.md)的 GitHub 存储库。

 AWS Encryption SDK 使用信封加密来保护您的数据。每条消息都使用唯一的数据密钥进行加密。然后，使用您指定的包装密钥加密数据密钥。要解密加密的邮件， AWS Encryption SDK 使用您指定的包装密钥来解密至少一个加密的数据密钥。然后其可解密加密文字并返回一条明文消息。

需要有关 AWS Encryption SDK所用术语方面的帮助？ 请参阅[中的概念 AWS Encryption SDK](concepts.md)。

## 如何 AWS Encryption SDK 加密数据
<a name="encrypt-workflow"></a>

 AWS Encryption SDK 提供了加密字符串、字节数组和字节流的方法。有关代码示例，请参阅各个 [编程语言](programming-languages.md) 部分的示例主题。

1. 创建指定用于保护您数据的包装密钥的[密钥环](choose-keyring.md)（或[主密钥提供程序](concepts.md#master-key-provider)）。

1. 将密钥环和明文数据传递给加密方法。建议您传入一个可选的非机密[加密上下文](concepts.md#encryption-context)。

1. 加密方法要求密钥环提供加密材料。密钥环返回消息的唯一数据加密密钥：一个纯文本数据密钥和一个由每个指定的包装密钥加密的数据密钥的副本。

1. 加密方法使用明文数据密钥加密数据，然后丢弃明文数据密钥。如果您提供加密上下文（ AWS Encryption SDK [最佳实践](best-practices.md)），加密方法会以加密方式将加密上下文绑定到加密的数据。

1. 加密方法返回一条[加密消息](concepts.md#message)，其中包含加密的数据、加密的数据密钥和包括加密上下文（如果有）在内的其他元数据。

## 如何 AWS Encryption SDK 解密加密的消息
<a name="decrypt-workflow"></a>

 AWS Encryption SDK 提供了解密[加密消息](concepts.md#message)并返回纯文本的方法。有关代码示例，请参阅各个 [编程语言](programming-languages.md) 部分的示例主题。

解密加密消息的[密钥环](choose-keyring.md)（或[主密钥提供程序](concepts.md#master-key-provider)）必须与用于加密消息的密钥环兼容。其中一个包装密钥必须能够解密加密消息中的加密数据密钥。有关与密钥环和主密钥提供程序的兼容性的信息，请参阅 [密钥环兼容性](choose-keyring.md#keyring-compatibility)。

1. 使用可解密数据的包装密钥创建密钥环或主密钥提供程序。您可以使用与加密方法相同的密钥环或其他密钥环。

1. 将[加密消息](concepts.md#message)和密钥环传递给解密方法。

1. 解密方法要求密钥环或主密钥提供程序解密加密消息中的一个加密数据密钥。它传入加密的消息中的信息，包括加密的数据密钥。

1. 密钥环使用其包装密钥以解密一个加密的数据密钥。如果成功，响应则包含明文数据密钥。如果密钥环或主密钥提供程序指定的包装密钥均无法解密加密数据密钥，则解密调用失败。

1. 解密方法使用明文数据密钥解密数据，丢弃明文数据密钥，然后返回明文数据。

# 中支持的算法套件 AWS Encryption SDK
<a name="supported-algorithms"></a>

*算法套件* 是一组加密算法和相关的值。加密系统使用算法实现生成密文消息。

该 AWS Encryption SDK 算法套件使用 Galois/Counter 模式下的高级加密标准 (AES) 算法 (GCM)，即 AES-GCM，对原始数据进行加密。 AWS Encryption SDK 支持 256 位、192 位和 128 位加密密钥。初始化向量 (IV) 长度始终为 12 字节。身份验证标签长度始终为 16 字节。

默认情况下， AWS Encryption SDK 使用带有 AES-GCM 的算法套件，该套件具有基于 HMAC 的 extract-and-expand密钥派生功能 (H [KDF](https://en.wikipedia.org/wiki/HKDF))、签名和 256 位加密密钥。如果[承诺策略](concepts.md#commitment-policy)需要[密钥承诺](concepts.md#key-commitment)，则 AWS Encryption SDK 会选择同时支持密钥承诺的算法套件；否则，它会选择具有密钥派生和签名功能但不支持密钥承诺的算法套件。

## 建议：具有密钥派生、签名和密钥承诺的 AES-GCM
<a name="recommended-algorithms"></a>

 AWS Encryption SDK 建议使用一种算法套件，该套件通过向基于 HMAC 的密钥派生函数 (H extract-and-expand KDF) 提供 256 位的数据加密密钥来获得 AES-GCM 加密密钥。 AWS Encryption SDK 添加了椭圆曲线数字签名算法 (ECDSA) 签名。为了支持[密钥承诺](concepts.md#key-commitment)，该算法套件还派生了一个*密钥承诺字符串*（一个非机密数据密钥标识符），该字符串存储在加密消息的元数据中。此密钥承诺字符串同样参照类似于数据加密密钥派生过程通过 HKDF 进行派生。


**AWS Encryption SDK 算法套件**  

| 加密算法 | 数据加密密钥长度（位） | 密钥派生算法 | 签名算法 | 密钥承诺 | 
| --- | --- | --- | --- | --- | 
| AES-GCM | 256 | HKDF 以及 SHA-384 | ECDSA 以及 P-384 和 SHA-384 | HKDF 以及 SHA-512 | 

HKDF 可以帮助您避免意外重用数据加密密钥，同时降低过度使用数据密钥的风险。

为了签名，该算法套件使用带加密哈希函数算法（SHA-384）的 ECDSA。默认情况下，将使用 ECDSA，即使基础主密钥的策略未指定该算法。[消息签名](concepts.md#digital-sigs)验证消息发件人是否有权加密消息，同时具有不可否认性。如果主密钥的授权策略允许一组用户加密数据，并允许一组不同的用户解密数据，这是特别有用的。

具有密钥承诺的算法套件确保每个加密文字仅解密为一个明文。这些算法套件通过验证用作加密算法输入的数据密钥的身份达到上述目的。加密时，这些算法套件会派生密钥承诺字符串。在解密之前，这些算法套件会验证数据密钥是否与密钥承诺字符串匹配。如果不匹配，Decrypt 调用会失败。

## 其他支持的算法套件
<a name="other-algorithms"></a>

 AWS Encryption SDK 支持以下备用算法套件以实现向后兼容。通常，我们不建议使用这些算法套件。但是，我们认识到签名会严重影响性能，因此我们针对这些情况提供了具有密钥派生的密钥提交套件。对于必须进行更显著的性能权衡的应用程序，我们将继续提供缺少签名、密钥承诺和密钥派生的套件。

**不具有密钥承诺的 AES-GCM**  
不具有密钥承诺的算法套件不会在解密之前验证数据密钥。因此，这些算法套件可能会将单个加密文字解密为不同的明文消息。但是，由于具有密钥承诺的算法套件会生成[稍大（\$130 字节）的加密消息](message-format.md)，并且处理时间更长，因此可能并非各应用程序的最佳选择。  
 AWS Encryption SDK 支持具有密钥派生、密钥承诺、签名的算法套件，以及具有密钥派生和密钥承诺但不支持签名的算法套件。我们不建议使用不具有密钥承诺的算法套件。如果必须使用，我们建议您使用具有密钥派生和密钥承诺但不支持签名的算法套件。但是，如果您的应用程序性能配置文件支持使用算法套件，最佳实践是使用具有密钥承诺、密钥派生和签名的算法套件。

**不具有签名的 AES-GCM**  
不具有签名的算法套件缺少具有真实性和不可否认性的 ECDSA 签名。如果同等信任加密和解密数据的用户，请仅使用此类套件。  
如果使用不具有签名的算法套件，我们建议您选择具有密钥派生和密钥承诺的算法套件。

**不具有密钥派生的 AES-GCM**  
不具有密钥派生的算法套件将数据加密密钥用作 AES-GCM 加密密钥，而非使用密钥派生函数派生唯一的密钥。我们不鼓励使用此套件生成密文，但出于兼容性考虑， AWS Encryption SDK 它们支持它。

有关如何在库中表示和使用这些套件的更多信息，请参阅[AWS Encryption SDK 算法参考](algorithms-reference.md)。