

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

# 什么是 AWS 数据库加密 SDK？
<a name="what-is-database-encryption-sdk"></a>


****  

|  | 
| --- |
| 我们的客户端加密库已重命名为 AWS 数据库加密 SDK。本开发人员指南仍提供有关 [DynamoDB 加密客户端](legacy-dynamodb-encryption-client.md)的信息。 | 

 AWS 数据库加密 SDK 是一组软件库，可让您在数据库设计中加入客户端加密。 AWS 数据库加密 SDK 提供记录级加密解决方案。您可以指定哪些字段经过加密，哪些字段包含在确保数据真实性的签名中。加密传输中敏感数据和静态敏感数据有助于确保您的明文数据不会提供给任何第三方，包括 AWS。 AWS 数据库加密 SDK 是根据 Apache 2.0 许可证免费提供的。

本开发人员指南提供了 AWS 数据库加密 SDK 的概念性概述，包括[其架构简介](concepts.md)、[它如何保护您的数据](how-it-works.md)、它与[服务器端加密](client-server-side.md)有何不同之处，以及[为应用程序选择关键组件](configure.md)以帮助您入门的指南。

 AWS 数据库加密软件开发工具包支持*具有*属性级加密功能的 Amazon DynamoDB。

 AWS 数据库加密 SDK 具有以下优点：

**专门针对数据库应用程序而设计**  
您无需成为密码专家即可使用 AWS 数据库加密 SDK。实施包括旨在处理您的现有应用程序的帮助程序方法。  
在创建和配置所需组件后，加密客户端在您将记录添加到数据库时以透明方式加密并签署这些记录，并且在检索记录时验证和解密它们。

**包括安全加密和签名**  
D AWS atabase Encryption SDK 包含安全的实现，即使用唯一的数据加密密钥对每条记录中的字段值进行加密，然后对记录进行签名以防止未经授权的更改，例如添加或删除字段或交换加密值。

**使用来自任何源的加密材料**  
 AWS 数据库加密 SDK 使用[密钥环](concepts.md#keyring-concept)生成、加密和解密保护您的记录的唯一数据加密密钥。密钥环决定加密该数据密钥的[包装密钥](concepts.md#wrapping-key)。  
您可以使用来自任何来源的包装密钥，包括加密服务，例如 [AWS Key Management Service](https://docs.aws.amazon.com/kms/latest/developerguide/)（AWS KMS）或 [AWS CloudHSM](https://docs.aws.amazon.com/cloudhsm/latest/userguide/)。 AWS 数据库加密 SDK 不需要 AWS 账户 任何 AWS 服务。

**支持加密材料缓存**  
[AWS KMS 分层密钥环](use-hierarchical-keyring.md)是一种加密材料缓存解决方案，它使用 AWS KMS 保存在Amazon DynamoDB表中的受保护*分支密钥*，然后在本地缓存用于加密和解密操作的分支密钥材料，从而减少 AWS KMS 调用次数。它允许您在对称加密 KMS 密钥下保护您的加密材料，而无需在 AWS KMS 每次加密或解密记录时都调用。对于需要最大限度地减少调用的应用程序来说， AWS KMS 分层密钥环是一个不错的 AWS KMS选择。

**可搜索的加密**  
您可以设计无需解密整个数据库即可搜索已加密记录的数据库。根据您的威胁模型和查询要求，您可以使用[可搜索的加密](searchable-encryption.md)对已加密数据库执行精确匹配搜索或更自定义的复杂查询。

**支持多租户数据库架构**  
Dat AWS abase Encryption SDK 使您能够使用不同的加密材料隔离每个租户，从而保护存储在共享架构的数据库中的数据。如果您有多个用户在数据库中执行加密操作，请使用其中一个 AWS KMS 密钥环为每个用户提供一个用于其加密操作的不同密钥。有关更多信息，请参阅 [使用多租户数据库](configure.md#config-multitenant-databases)。

**支持无缝架构更新**  
在配置 AWS 数据库加密 SDK 时，您需要提供[加密操作](concepts.md#crypt-actions)，告诉客户端要加密和签名哪些字段，哪些字段需要签名（但不加密），以及要忽略哪些字段。使用 AWS 数据库加密 SDK 保护记录后，您仍然可以[对数据模型进行更改](ddb-update-data-model.md)。您可以在单个部署中更新您的加密操作，例如添加或移除已加密的字段。

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

 AWS 数据库加密 SDK 是在上的开源存储库中开发的 GitHub。您可以使用这些存储库查看代码、阅读和提交问题，并且查找特定于您的实施的信息。

**适用于 DynamoDB 的 AWS 数据库加密 SDK**
+ 上的 [aws-database-encryption-sdk-dynamodb](https://github.com/aws/aws-database-encryption-sdk-dynamodb/) 存储库 GitHub 支持 Java、.NET 和 Rust 中最新版本的 DynamoDB AWS 数据库加密 SDK。

  适用于 DynamoDB 的 AWS 数据库加密 SDK 是 Dafny [的](https://github.com/dafny-lang/dafny/blob/master/README.md)产品，Dafny 是一种验证感知语言，你可以用它来编写规范、实现规范、代码和测试规范。结果为在确保功能正确性的框架中实施适用于 DynamoDB 的 AWS 数据库加密 SDK 功能的库。

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

 AWS 数据库加密 SDK 使用与 AWS SDK 和工具相同的[维护策略](https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html)，包括版本控制和生命周期阶段。作为最佳实践，建议您使用适用于您的数据库实现的 AWS 数据库加密 SDK 的最新可用版本，并在新版本发布时进行升级。

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

## 发送反馈
<a name="feedback"></a>

我们欢迎您提供反馈！如果您有任何疑问或意见或者要报告问题，请使用以下资源。

如果您在 AWS 数据库加密 SDK 中发现潜在的安全漏洞，请[通知 AWS 安全部门](https://aws.amazon.com/security/vulnerability-reporting/)。不要创建公开 GitHub 问题。

要提供对本文档的反馈，请使用任何页面上的反馈链接。

# AWS 数据库加密 SDK 概念
<a name="concepts"></a>


****  

|  | 
| --- |
| 我们的客户端加密库已重命名为 AWS 数据库加密 SDK。本开发人员指南仍提供有关 [DynamoDB 加密客户端](legacy-dynamodb-encryption-client.md)的信息。 | 

本主题介绍 AWS 数据库加密 SDK 中使用的概念和术语。

要了解 AWS 数据库加密 SDK 的组件是如何交互的，请参阅[AWS 数据库加密 SDK 的工作原理](how-it-works.md)。

要了解有关 AWS 数据库加密 SDK 的更多信息，请参阅以下主题。
+ 了解 AWS 数据库加密 SDK 如何使用[信封加密](#envelope-encryption)来保护您的数据。
+ 了解信封加密的要素：保护记录的[数据密钥](#data-key)以及保护数据密钥的[包装密钥](#wrapping-key)。
+ 了解决定您使用哪种包装密钥的[密钥环](#keyring-concept)。
+ 了解可增强加密过程完整性的[加密上下文](#encryption-context)。
+ 了解加密方法在您的记录中添加的[材料描述](#material-description)。
+ 了解告诉 AWS 数据库加密 SDK 要加密和签名的字段的[加密操作](#crypt-actions)。

**Topics**
+ [信封加密](#envelope-encryption)
+ [数据密钥](#data-key)
+ [包装密钥](#wrapping-key)
+ [密钥环](#keyring-concept)
+ [加密操作](#crypt-actions)
+ [材料描述](#material-description)
+ [加密上下文](#encryption-context)
+ [加密材料管理器](#crypt-materials-manager)
+ [对称和非对称加密](#symmetric-key-encryption)
+ [密钥承诺](#key-commitment)
+ [数字签名](#digital-sigs)

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

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

**保护数据密钥**  
 AWS 数据库加密 SDK 使用唯一的数据密钥对每个字段进行加密。然后，对您指定的包装密钥下的每个数据密钥进行加密。它将已加密的数据密钥存储在[材料描述](#material-description)中。  
要指定包装密钥，您可以使用[密钥环](#keyring-concept)。  

![\[使用 AWS 数据库加密 SDK 进行信封加密\]](http://docs.aws.amazon.com/zh_cn/database-encryption-sdk/latest/devguide/images/dbesdk-envelope.png)


**在多个包装密钥下加密相同的数据**  
您可以使用多个包装密钥加密数据密钥。您可能希望为不同的用户提供不同的包装密钥，或者提供不同类型的包装密钥，或者位于不同的位置。每个包装密钥都加密相同的数据密钥。 AWS 数据库加密 SDK 将所有加密的数据密钥与[材料描述](#material-description)中的加密字段一起存储。  
要解密数据，您需要至少提供一个可以解密已加密数据密钥的包装密钥。

**结合多种算法的优势**  
[为了加密您的数据，默认情况下， AWS 数据库加密 SDK 使用[带有 AES-GCM 对称加密、基于 HMAC 的密钥派生函数 (HKDF) 和 ECDSA 签名的算法套件](supported-algorithms.md)。](#digital-sigs)要加密数据密钥，您可以指定适合您的包装密钥的[对称或非对称加密算法](#symmetric-key-encryption)。  
通常，与非对称或*公有密钥加密* 相比，对称密钥加密算法速度更快，生成的密文更小。但公有密钥算法可提供固有的角色分离。为了结合每种算法的优势，您可以使用公有密钥加密功能加密数据密钥。  
我们建议尽可能使用其中一个 AWS KMS 钥匙圈。使用[AWS KMS 密钥环](use-kms-keyring.md)时，您可以选择通过将非对称 RSA AWS KMS key 指定为包装密钥来组合多种算法的优势。您也可以使用对称加密 KMS 密钥。

## 数据密钥
<a name="data-key"></a>

*数据密钥*是一种加密密钥， AWS 数据库加密 SDK 使用它来加密记录中在[加密操作`ENCRYPT_AND_SIGN`](#crypt-actions)中标记的字段。每个数据密钥都是一个符合加密密钥要求的字节数组。 AWS 数据库加密 SDK 使用唯一的数据密钥来加密每个属性。

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

[为了保护您的数据密钥， AWS 数据库加密 SDK 使用一个或多个密*钥加密密钥（称为包装密钥）对其进行加密*。](#wrapping-key)在 AWS 数据库加密 SDK 使用您的纯文本数据密钥加密您的数据后，它会尽快将其从内存中删除。然后再将加密的数据密钥存储在[材料描述](#material-description)中。有关更多信息，请参阅 [AWS 数据库加密 SDK 的工作原理](how-it-works.md)。

**提示**  
在 AWS 数据库加密 SDK 中，我们将*数据密钥与数据**加密密钥*区分开来。作为最佳实践，支持的所有[算法套件](supported-algorithms.md)都使用[密钥派生函数](https://en.wikipedia.org/wiki/Key_derivation_function)。密钥派生函数将数据密钥作为输入，并返回实际用于加密记录的数据加密密钥。因此，我们通常说数据是“根据”数据密钥加密的，而不是“由”数据密钥加密的。

每个加密的数据密钥都包含元数据，包括对其进行加密的包装密钥的标识符。此元数据使 AWS 数据库加密 SDK 能够在解密时识别有效的包装密钥。

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

*包装密钥*是一种密钥加密密钥， AWS 数据库加密 SDK 使用它来加密用于加密记录的[数据密钥](#data-key)。可以使用一个或多个包装密钥加密每个数据密钥。在配置[密钥环](#keyring-concept)时，您可以决定使用哪些包装密钥来保护您的数据。

![\[使用多个包装密钥加密一个数据密钥\]](http://docs.aws.amazon.com/zh_cn/database-encryption-sdk/latest/devguide/images/dbesdk-wrapping-key.png)


 AWS 数据库加密 SDK 支持多种常用的封装密钥，例如 [AWS Key Management Service](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys)(AWS KMS) 对称加密 KMS 密钥（包括[多区域密钥）和非对称 [RSA KMS AWS KMS 密钥](https://docs.aws.amazon.com/kms/latest/developerguide/asymmetric-key-specs.html#key-spec-rsa)](use-kms-keyring.md#config-mrks)、原始 AES-GCM（高级加密 Standard/Galois 计数器模式）密钥和原始 RSA 密钥。建议尽量使用 KMS 密钥。要决定应当使用哪个包装密钥，请参阅[选择包装密钥](configure.md#config-keys)。

在使用信封加密时，您需要保护包装密钥以防止未经授权的访问。您可以通过以下任何方式来执行此操作：
+ 使用专用于该用途的服务，如 [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 数据库加密 SDK AWS KMS 与集成，可帮助您保护和使用包装密钥。

## 密钥环
<a name="keyring-concept"></a>

要指定用于加密和解密的包装密钥，您可以使用密钥环。您可以使用 AWS 数据库加密 SDK 提供的密钥环，也可以设计自己的实现。

*密钥环* 生成、加密和解密数据密钥。它还会生成用于计算签名中基于哈希的消息身份验证码 (HMACs) 的 MAC 密钥。定义密钥环时，您可以指定用于加密数据密钥的[包装密钥](#wrapping-key)。大多数密钥环至少指定一个包装密钥或一项提供和保护包装密钥的服务。加密时， AWS 数据库加密 SDK 使用密钥环中指定的所有包装密钥来加密数据密钥。有关选择和使用 AWS 数据库加密 SDK 定义的密钥环的帮助，请参阅[使用密钥](keyrings.md)环。

## 加密操作
<a name="crypt-actions"></a>

*加密操作*告诉加密程序要对记录中的每个字段执行哪些操作。

加密操作值可以是以下任何值：
+ **加密并签名** – 加密字段。在签名中包含加密的字段。
+ **仅签名** – 在签名中包含该字段。
+ **在加密上下文中签名并**包含-将该字段包含在签名和[加密上下文](#encryption-context)中。

  默认情况下，分区和排序密钥是加密上下文中唯一包含的属性。您可以考虑定义其他字段，`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`以便分[AWS KMS 层密钥环](use-hierarchical-keyring.md)的分支密钥 ID 提供者可以识别从加密上下文中解密需要哪个分支密钥。有关更多信息，请参阅[分支密钥 ID 供应商](use-hierarchical-keyring.md#branch-key-id-supplier)。
**注意**  
要使用`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`加密操作，必须使用 AWS 数据库加密 SDK 的 3.3 或更高版本。在[更新要包含的数据模型之前，先将](ddb-update-data-model.md)新版本部署给所有读者`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`。
+ **不执行任何操作** – 不加密或在签名中包含该字段。

对于可能存储敏感数据的任何字段，请使用**加密和签名**。对于主键值（例如，DynamoDB 表中的分区键和排序键），**请使用仅签名或签名****并包含**在加密上下文中。如果您指定了任何 “**签名” 并包含在加密上下文**中，则分区和排序属性也必须为 “**签名” 并包含在加密上下文**中。您不需要为[材料描述](#material-description)指定加密操作。 AWS 数据库加密 SDK 会自动对存储材料描述的字段进行签名。

请谨慎选择您的加密操作。如有怀疑，请使用 **Encrypt and sign (加密和签名)**。使用 AWS 数据库加密 SDK 保护记录后，不能将现有`ENCRYPT_AND_SIGN``SIGN_ONLY`、或`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`字段更改为现有字段`DO_NOTHING`，也不能更改分配给现有`DO_NOTHING`字段的加密操作。但是，您仍可以[对数据模型进行其他更改](ddb-update-data-model.md)。例如，您可以在单个部署中添加或移除加密字段。

## 材料描述
<a name="material-description"></a>

材料描述将用作加密记录的标题。当您使用 AWS 数据库加密 SDK 对字段进行加密和签名时，加密器会在组装加密材料时记录材料描述，并将材料描述存储在加密器添加到记录中的新字段 (`aws_dbe_head`) 中。

材料描述是一种可移植的[格式化数据结构](reference.md#material-description-format)，其中包含数据密钥和其他信息的加密副本，例如加密算法、[加密上下文](#encryption-context)以及加密和签名指令。加密程序将在汇编用于加密和签名的加密材料时记录材料描述。之后，当它需要汇编加密材料以验证和解密字段时，它将使用材料描述作为指南。

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

有关材料描述的技术信息，请参阅 [材料描述的格式](reference.md#material-description-format)。

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

为了提高加密操作的安全性， AWS 数据库加密 SDK 在所有加密和签署记录的请求中都包含加密上下文。

*加密上下文* 是一组名称值对，其中包含任意非机密经过身份验证的附加数据。 AWS 数据库加密 SDK 在加密环境中包含数据库的逻辑名称和主键值（例如，DynamoDB 表中的分区键和排序键）。当您加密和签名字段时，加密上下文以加密方式绑定到加密的记录，以便需要使用相同的加密上下文解密字段。

如果您使用 AWS KMS 密钥环，则 AWS 数据库加密 SDK 还会使用加密上下文在密钥环的调用中提供其他经过身份验证的数据 (AAD)。 AWS KMS

每当您使用[默认算法套件](supported-algorithms.md#recommended-algorithms)时，[加密材料管理程序](#crypt-materials-manager)（CMM）都会向加密上下文（由保留名称、`aws-crypto-public-key` 和表示公有验证密钥的值组成）添加一个名称/值对。公有验证密钥存储在[材料描述](#material-description)中。

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

加密材料管理器（CMM）汇编用于加密、解密和对数据进行签名的加密材料。每当您使用[默认算法套件](supported-algorithms.md#recommended-algorithms)时，*加密材料*都会包括明文和加密的数据密钥、对称签名密钥以及非对称签名密钥。您永远不会直接与 CMM 交互。加密和解密方法替您进行处理。

由于 CMM 充当 AWS 数据库加密 SDK 和密钥环之间的联络人，因此它是自定义和扩展（例如支持策略实施）的理想场所。您可以明确指定 CMM，但这不是必需的。当您指定密钥环时， AWS 数据库加密 SDK 会为您创建一个默认 CMM。默认 CMM 从您指定的密钥环获取加密或解密材料。这可能涉及调用一个加密服务，如 [AWS Key Management Service](https://docs.aws.amazon.com/kms/latest/developerguide/) (AWS KMS)。

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

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

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

 AWS 数据库加密 SDK 使用[信封加密](#envelope-encryption)。使用对称数据密钥加密您的数据。使用一个或多个对称或非对称包装密钥加密对称数据密钥。它在记录中添加了[材料描述](#material-description)，其中至少包括一个数据密钥的加密副本。

**加密您的数据（对称加密）**  
为了加密您的数据， AWS 数据库加密 SDK 使用对称[数据密钥](#data-key)和包含对称加密[算法的算法套件](supported-algorithms.md)。要解密数据， AWS 数据库加密 SDK 使用相同的数据密钥和相同的算法套件。

**加密您的数据密钥（对称或非对称加密）**  
您为加密和解密操作提供的[密钥环](#keyring-concept)决定了对称数据密钥的加密和解密方式。您可以选择使用对称加密的密钥环，例如带有对称加密 KMS AWS KMS 密钥的密钥环，也可以选择使用非对称加密的密钥环，例如带有非对称 RSA KMS 密钥的 AWS KMS 密钥环。

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

 AWS 数据库加密 SDK 支持*密钥承诺*（有时称为*稳健性*），这是一种安全属性，可确保每个密文只能解密为单个纯文本。为此，密钥承诺确保仅使用加密记录的数据密钥来解密消息。 AWS 数据库加密 SDK 包括所有加密和解密操作的密钥承诺。

大多数现代对称密码（包括 AES）使用单个密钥对纯文本进行加密，例如 AWS 数据库加密 SDK 用来加密记录中标记的每个纯文本字段的[唯一数据密钥](#data-key)。`ENCRYPT_AND_SIGN`使用相同的数据密钥解密这些记录会返回与原始数据相同的明文。使用不同的密钥解密通常会失败。虽然困难，但在技术上有可能使用两个不同的密钥解密加密文字。在极少数情况下，找到一个可以将加密文字不分解密成不同但仍然可以理解的明文的密钥是可行的。

 AWS 数据库加密 SDK 始终使用一个唯一的数据密钥对每个属性进行加密。可能会使用多个包装密钥加密该数据密钥，但包装密钥始终加密相同的数据密钥。尽管如此，手动制作的复杂加密的记录实际上可能包含不同的数据密钥，每个数据密钥都由不同的包装密钥加密。例如，如果一个用户对加密的记录进行解密，将返回 0x0（false），而另一个用户解密相同的加密记录则得到 0x1（true）。

为防止出现这种情况， AWS 数据库加密 SDK 在加密和解密时包含密钥承诺。加密方法以加密方式将生成加密文字的唯一数据密钥与*密钥承诺*绑定，密钥承诺是一种 HMAC 散列消息认证码（HMAC），使用数据密钥的推导根据材料描述计算得出。然后它将密钥承诺存储在[材料描述](#material-description)中。当使用密钥承诺解密记录时， AWS 数据库加密 SDK 会验证数据密钥是否是该加密记录的唯一密钥。如果数据密钥验证失败，则解密操作将失败。

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

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

为避免此问题，[默认算法套件](supported-algorithms.md#recommended-algorithms)将椭圆曲线数字签名算法（ECDSA）签名添加到加密记录中。默认算法套件使用经过身份验证的加密算法 AES-GCM 对记录中标记为 `ENCRYPT_AND_SIGN` 的字段进行加密。然后，它会计算记录中标`ENCRYPT_AND_SIGN`有、和的字段上的基于哈希的消息身份验证码 (HMACs) 和非对称 ECDSA 签名。`SIGN_ONLY` `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`解密过程使用签名来验证授权用户是否对记录进行了加密。

使用默认算法套件时， AWS 数据库加密 SDK 会为每条加密记录生成临时私钥和公钥对。 AWS 数据库加密 SDK 将公钥存储在[材料描述](#material-description)中，并丢弃私钥。这样可以确保任何人都无法创建另一个使用公钥进行验证的签名。该算法将公钥与加密的数据密钥绑定为材料描述中的其他经过身份验证的数据，从而防止只能解密字段的用户更改公钥或影响签名验证。

 AWS 数据库加密 SDK 始终包含 HMAC 验证。默认情况下，ECDSA 数字签名启用，但不是必需的。如果加密数据的用户和解密数据的用户同样受到信任，您可能会考虑使用不包括数字签名的算法条件以改进性能。有关选择替代算法套件的更多信息，参阅[选择算法套件](ddb-java-using.md#config-algorithm)。

**注意**  
如果密钥环未在加密器和解密器之间划清界限，则数字签名不提供任何加密价值。

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

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

# AWS 数据库加密 SDK 的工作原理
<a name="how-it-works"></a>


****  

|  | 
| --- |
| 我们的客户端加密库已重命名为 AWS 数据库加密 SDK。本开发人员指南仍提供有关 [DynamoDB 加密客户端](legacy-dynamodb-encryption-client.md)的信息。 | 

 AWS 数据库加密 SDK 提供专为保护存储在数据库中的数据而设计的客户端加密库。库包含可以直接扩展或使用的安全实施。有关定义和使用自定义组件的更多信息，请参阅数据库实现的 GitHub 存储库。

本节中的工作流程说明了 AWS 数据库加密 SDK 如何对数据库中的数据进行加密、签名、解密和验证。这些工作流使用抽象元素和默认特征描述基本流程。有关 AWS 数据库加密 SDK 如何与您的数据库实现配合使用的详细信息，请参阅数据库的*加密内容*主题。

 AWS 数据库加密 SDK 使用[信封加密](concepts.md#envelope-encryption)来保护您的数据。每条记录都使用唯一的[数据密钥](concepts.md#data-key)进行加密。数据密钥用于为加密操作中标记为 `ENCRYPT_AND_SIGN` 的每个字段派生唯一的*数据加密密钥*。然后，使用您指定的包装密钥对数据密钥副本进行加密。要解密加密记录， AWS 数据库加密 SDK 使用您指定的包装密钥来解密至少一个加密的数据密钥。然后其可解密加密文字并返回一条明文条目。

有关 AWS 数据库加密 SDK 中使用的术语的更多信息，请参阅[AWS 数据库加密 SDK 概念](concepts.md)。

## 加密并签名
<a name="encrypt-and-sign"></a>

 AWS 数据库加密 SDK 的核心是一个记录加密器，用于对数据库中的记录进行加密、签名、验证和解密。它取得您的记录的信息，以及要加密和签名的字段说明。它将从通过您指定的包装密钥配置的[加密材料提供程序](concepts.md#crypt-materials-manager)获取加密材料和加密材料的使用说明。

以下演练描述了 AWS 数据库加密 SDK 如何对您的数据条目进行加密和签名。

1. 加密材料管理器为 AWS 数据库加密 SDK 提供了唯一的数据加密密钥：一个纯文本[数据密钥](concepts.md#data-key)、一份由指定[包装密钥加密的数据密钥副本和一个 MAC 密钥](concepts.md#wrapping-key)。
**注意**  
您可以使用多个包装密钥加密数据密钥。每个包装密钥加密数据密钥的单独副本。 AWS 数据库加密 SDK 将所有加密的数据密钥存储在[材料描述](concepts.md#material-description)中。 AWS 数据库加密 SDK 在记录中添加一个用于存储材料描述的新字段（`aws_dbe_head`）。  
为数据密钥的每个加密副本派生一个 MAC 密钥。MAC 密钥不存储在材料描述中。反之，解密方法使用包装密钥再次派生 MAC 密钥。

1. 加密方法对您指定的[加密操作](concepts.md#crypt-actions)中标记为 `ENCRYPT_AND_SIGN` 的每个字段进行加密。

1. 加密方法从数据密钥中派生 `commitKey`，并使用它生成[密钥承诺值](concepts.md#key-commitment)，然后再丢弃该数据密钥。

1. 加密方法将[材料描述](concepts.md#material-description)添加到记录中。材料描述包含加密的数据密钥以及有关加密记录的其他信息。有关材料描述中包含的信息的完整列表，请参阅[材料描述格式](reference.md#material-description-format)。

1. 加密方法使用**步骤 1** 中返回的 MAC 密钥来计算基于哈希的消息身份验证码 (HMAC) 值，而不是材料描述、[加密上下文以及加密](concepts.md#encryption-context)操作中标记`ENCRYPT_AND_SIGN`的每个字段的规范化。`SIGN_ONLY` `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`HMAC 值存储在加密方法添加到记录的新字段（`aws_dbe_foot`）中。

1. 加密方法根据材料描述、加密上下文和每个标有 `ENCRYPT_AND_SIGN` “或`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`” 的字段的规范化计算 [ECDSA 签名](concepts.md#digital-sigs)，并将 ECDSA 签名存储在字段中。`SIGN_ONLY` `aws_dbe_foot`
**注意**  
默认情况下，ECDSA 签名处于启用状态，但不是必需的。

1. 加密方法将已加密和签名的记录存储在您的数据库中

## 解密并验证
<a name="decrypt-and-verify"></a>

1. 加密材料管理器（CMM）提供解密方法，其中解密材料存储在材料描述中，包括明本[数据密钥](concepts.md#data-key)和关联的 MAC 密钥。

   1. CMM 使用指定的密钥环中的[包装密钥](concepts.md#wrapping-key)为加密的数据密钥解密，然后返回明文数据密钥。

1. 解密方法比较并验证材料描述中的密钥承诺值。

1. 解密方法可验证签名字段中的签名。

   它`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`从您定义的[允许未经身份验证的字段列表中识别哪些字段已](ddb-java-using.md#allowed-unauth)标记`ENCRYPT_AND_SIGN``SIGN_ONLY`、或。解密方法使用**步骤 1** 中返回的 MAC 密钥重新计算和比较标记为、或的字段的 HMAC 值。`ENCRYPT_AND_SIGN` `SIGN_ONLY` `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`然后，它使用存储在[加密上下文](concepts.md#encryption-context)中的公有密钥来验证 [ECDSA 签名](concepts.md#digital-sigs)。

1. 解密方法使用明文数据密钥解密标记为 `ENCRYPT_AND_SIGN` 的每个值。然后， AWS 数据库加密 SDK 会丢弃纯文本数据密钥。

1. 解密方法返回明文记录。

# AWS 数据库加密 SDK 中支持的算法套件
<a name="supported-algorithms"></a>


****  

|  | 
| --- |
| 我们的客户端加密库已重命名为 AWS 数据库加密 SDK。本开发人员指南仍提供有关 [DynamoDB 加密客户端](legacy-dynamodb-encryption-client.md)的信息。 | 

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

 AWS 数据库加密 SDK 使用算法套件对数据库中的字段进行加密和签名。所有支持的算法套件都使用带 Galois/Counter 模式 (GCM) 的高级加密标准 (AES) 算法（称为 AES-GCM）来加密原始数据。 AWS 数据库加密 SDK 支持 256 位加密密钥。身份验证标签长度始终为 16 字节。


**AWS 数据库加密 SDK 算法套件**  

| 算法 | 加密算法 | 数据密钥长度（位） | 密钥派生算法 | 对称签名算法 | 非对称签名算法 | 密钥承诺 | 
| --- | --- | --- | --- | --- | --- | --- | 
| 默认 | AES-GCM | 256 | HKDF 以及 SHA-512 | HMAC-SHA-384 | ECDSA 以及 P-384 和 SHA-384 | HKDF 以及 SHA-512 | 
| 没有 ECDSA 数字签名的 AES-GCM | AES-GCM | 256 | HKDF 以及 SHA-512 | HMAC-SHA-384 | 无 | HKDF 以及 SHA-512 | 

**加密算法**  
与加密算法一起使用的名称和模式。 AWS 数据库加密 SDK 中的算法套件使用带 Galois/Counter 模式 (GCM) 的高级加密标准 (AES) 算法。  


**数据密钥长度**  
[数据密钥](concepts.md#data-key)的长度（以位为单位）。 AWS 数据库加密 SDK 支持 256 位数据密钥。数据密钥用作基于 HMAC 的密 extract-and-expand钥派生函数 (HKDF) 的输入。HKDF 的输出用作加密算法中的数据加密密钥。

**密钥派生算法**  
基于 HMAC 的 extract-and-expand密钥派生函数 (HKDF)，用于派生数据加密密钥。 AWS 数据库加密 SDK 使用 [RFC](https://tools.ietf.org/html/rfc5869) 5869 中定义的 HKDF。  
+ 使用的哈希函数是 SHA-512
+ 对于提取步骤：
  + 不使用加密盐。根据 RFC，加密盐设置为包含零的字符串。
  + [输入密钥材料是密钥环中的数据密钥。](concepts.md#keyring-concept)
+ 对于扩展步骤：
  + 输入伪随机密钥是提取步骤的输出。
  + 密钥标签是按大端字节顺序排列的 `DERIVEKEY` 字符串的 UTF-8 编码字节。
  + 输入信息是将算法 ID 和密钥标签（按此顺序）串联在一起的结果。
  + 输出加密材料的长度是**数据密钥长度**。该输出用作加密算法中的数据加密密钥。

**对称签名算法**  
用于生成对称签名的基于哈希的消息身份验证码 (HMAC) 算法。所有支持的算法套件都包含 HMAC 验证。  
 AWS 数据库加密 SDK 对材料描述和所有标有`ENCRYPT_AND_SIGN``SIGN_ONLY`、或`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`的字段进行序列化。然后，它使用带有加密哈希函数算法 (SHA-384) 的 HMAC 对规范化进行签名。  
对称 HMAC 签名存储在 AWS 数据库加密 SDK 添加到记录中的新字段 (`aws_dbe_foot`) 中。

**非对称签名算法**  
用于生成非对称数字签名的签名算法。  
 AWS 数据库加密 SDK 对材料描述和所有标有`ENCRYPT_AND_SIGN``SIGN_ONLY`、或`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`的字段进行序列化。然后，它使用具有以下细节的椭圆曲线数字签名算法 (ECDSA) 对规范化进行签名：  
+ 使用的椭圆曲线是 P-384，定义见[数字签名标准 (DSS) (FIPS PUB 186-4)](http://doi.org/10.6028/NIST.FIPS.186-4)。
+ 使用的哈希函数是 SHA-384。
非对称 ECDSA 签名与现场对称 HMAC 签名一起存储。`aws_dbe_foot`  
默认情况下包括 ECDSA 数字签名，但不是必需的。

**密钥承诺**  
基于 HMAC 的 extract-and-expand密钥派生函数 (HKDF) 用于派生提交密钥。  
+ 使用的哈希函数是 SHA-512
+ 对于提取步骤：
  + 不使用加密盐。根据 RFC，加密盐设置为包含零的字符串。
  + [输入密钥材料是密钥环中的数据密钥。](concepts.md#keyring-concept)
+ 对于扩展步骤：
  + 输入伪随机密钥是提取步骤的输出。
  + 输入信息是按大字节顺序排列的`COMMITKEY`字符串的 UTF-8 编码字节。
  + 输出键控材料的长度为 256 位。此输出用作提交密钥。
[提交密钥计算[记录承诺](reference.md#format-commitment)，即不同的 256 位基于哈希的消息身份验证码 (HMAC) 哈希，而不是材料描述。](reference.md#material-description-format)有关向算法套件添加密钥承诺的技术说明，请参阅 Cryptology ePrint Archive AEADs 中的[密钥提交](https://eprint.iacr.org/2020/1153)。

## 默认的算法套件
<a name="recommended-algorithms"></a>

默认情况下， AWS 数据库加密 SDK 使用带有 AES-GCM、基于 HMAC 的 extract-and-expand密钥派生函数 (HKDF)、HMAC 验证、ECDSA 数字签名、密钥承诺和 256 位加密密钥的算法套件。

默认算法套件包括 HMAC 验证（对称签名）和 [ECDSA 数字签名（非对称签名](concepts.md#digital-sigs)）。这些签名存储在 AWS 数据库加密 SDK 添加到记录中的新字段 (`aws_dbe_foot`) 中。当授权策略允许一组用户加密数据，允许另一组用户解密数据时，ECDSA 数字签名特别有用。

默认算法套件还会派生一个[密钥承诺](concepts.md#key-commitment) ——一个将数据密钥与记录关联的 HMAC 哈希。密钥承诺值是根据材料描述和提交密钥计算得出的 HMAC。然后，密钥承诺值将存储在材料描述中。密钥承诺确保每个加密文字仅解密为一个明文。这些算法套件通过验证用作加密算法输入的数据密钥达到上述目的。加密时，算法套件会派生密钥承诺 HMAC。在解密之前，这些算法套件会验证数据密钥是否生成相同的密钥承诺 HMAC。如果没有，Decrypt 调用会失败。

## 没有 ECDSA 数字签名的 AES-GCM
<a name="other-algorithms"></a>

尽管默认算法套件可能适用于大多数应用程序，但您可以选择其他算法套件。例如，没有ECDSA数字签名的算法套件可以满足某些信任模型。仅当加密数据的用户和解密数据的用户同样受到信任时，才使用此套件。

所有 AWS 数据库加密 SDK 算法套件都包含 HMAC 验证（对称签名）。唯一的区别是，没有ECDSA数字签名的AES-GCM算法套件缺少提供额外真实性和不可否认性的非对称签名。

例如，如果您的密钥环、、和中有多个包装密钥 `wrappingKeyA``wrappingKeyB`，并且您使用`wrappingKeyA`解密记录`wrappingKeyC`，则 HMAC 对称签名会验证该记录是否由有权访问的用户加密。`wrappingKeyA`如果您使用默认算法套件，则会 HMACs提供相同的验证`wrappingKeyA`，并使用 ECDSA 数字签名来确保记录由具有加密权限的用户加密。`wrappingKeyA`

要选择不带数字签名的 AES-GCM 算法套件，请在加密配置中加入以下片段。

------
#### [ Java ]

以下代码段指定了没有 ECDSA 数字签名的 AES-GCM 算法套件。有关更多信息，请参阅 [适用于 DynamoDB 的 AWS 数据库加密 SDK 中的加密配置](ddb-java-using.md#ddb-config-encrypt)。

```
.algorithmSuiteId(
    DBEAlgorithmSuiteId.ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY_SYMSIG_HMAC_SHA384)
```

------
#### [ C\$1 / .NET ]

以下代码段指定了没有 ECDSA 数字签名的 AES-GCM 算法套件。有关更多信息，请参阅 [适用于 DynamoDB 的 AWS 数据库加密 SDK 中的加密配置](ddb-net-using.md#ddb-net-config-encrypt)。

```
AlgorithmSuiteId = DBEAlgorithmSuiteId.ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY_SYMSIG_HMAC_SHA384
```

------
#### [ Rust ]

以下代码段指定了没有 ECDSA 数字签名的 AES-GCM 算法套件。有关更多信息，请参阅 [适用于 DynamoDB 的 AWS 数据库加密 SDK 中的加密配置](ddb-rust-using.md#ddb-rust-config-encrypt)。

```
.algorithm_suite_id(
    DbeAlgorithmSuiteId::AlgAes256GcmHkdfSha512CommitKeyEcdsaP384SymsigHmacSha384,
)
```

------