

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

# 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 钥匙圈