AWS Encryption SDK中的概念 - AWS Encryption SDK

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

AWS Encryption SDK中的概念

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

需要帮助?

信封加密

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

保护数据密钥

AWS Encryption SDK 使用唯一的数据密钥加密每条消息。然后,对您指定的包装密钥下的数据密钥进行加密。将加密的数据密钥与加密的数据一并存储在其返回的加密消息中。

要指定包装密钥,请使用密钥环主密钥提供程序

使用 AWS Encryption SDK 进行信封加密
在多个包装密钥下加密相同的数据

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

要解密数据,您需要提供可以解密任一加密数据密钥的包装密钥。

每个包装密钥对相同的数据密钥进行加密,从而为每个包装密钥生成一个加密的数据密钥
结合多种算法的优势

要加密您的数据,默认情况下,AWS Encryption SDK 使用具有 AES-GCM 对称加密、密钥派生函数(HKDF)和签名的复杂算法套件。要加密数据密钥,您可以指定适合您的包装密钥的对称或非对称加密算法

通常,与非对称或公有密钥加密 相比,对称密钥加密算法速度更快,生成的密文更小。但公有密钥算法可提供固有的角色分离和更轻松的密钥管理。为了结合每种算法的优势,您可以使用对称密钥加密功能加密数据,然后使用公有密钥加密功能加密数据密钥。

数据密钥

数据密钥 是 AWS Encryption SDK用于加密数据的加密密钥。每个数据密钥都是一个符合加密密钥要求的字节数组。除非您使用数据密钥缓存,否则 AWS Encryption SDK使用唯一数据密钥加密每条消息。

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

为了保护您的数据密钥,AWS Encryption SDK 使用一个或多个密钥加密密钥(称为包装密钥或主密钥)对其进行加密。AWS Encryption SDK使用您的明文数据密钥加密数据后,会尽快将其从内存中删除。然后,它将加密的数据密钥与加密的数据一并存储在加密操作返回的加密消息中。有关详细信息,请参阅AWS Encryption SDK的工作方式

提示

在 AWS Encryption SDK中,我们将数据密钥数据加密密钥 区分开来。一些支持的算法套件(包括默认套件)使用密钥派生函数以防止数据密钥达到其加密限制。密钥派生函数将数据密钥作为输入,并返回实际用于加密数据的数据加密密钥。因此,我们通常说数据是“根据”数据密钥加密的,而不是“由”数据密钥加密的。

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

包装密钥

包装密钥是一种密钥加密密钥,AWS Encryption SDK 使用该密钥加密用于加密数据的数据密钥。可以使用一个或多个包装密钥加密每个明文数据密钥。在配置密钥环主密钥提供程序时,您可以决定使用哪些包装密钥来保护您的数据。

注意

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

AWS Encryption SDK 支持几个常用的包装密钥,例如 AWS Key Management Service(AWS KMS)对称 AWS KMS keys(包括多区域 KMS 密钥)、原始 AES-GCM(高级加密标准/伽罗瓦计数器模式)密钥和原始 RSA 密钥。您还可以扩展或实施自己的包装密钥。

在使用信封加密时,您需要保护包装密钥以防止未经授权的访问。您可以通过以下任何方式来执行此操作:

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

密钥环和主密钥提供程序

要指定用于加密和解密的包装密钥,您可以使用密钥环(C、C# /.NET 和 JavaScript)或主密钥提供程序(Java、Python、CLI)。您可以使用 AWS Encryption SDK 提供的密钥环和主密钥提供程序,也可以设计自己的实现。AWS Encryption SDK 提供相互兼容的密钥环和主密钥提供程序,但须遵守语言限制。有关详细信息,请参阅密钥环兼容性

密钥环 生成、加密和解密数据密钥。定义密钥环时,可以指定用于加密数据密钥的包装密钥。大多数密钥环至少指定一个包装密钥或一项提供和保护包装密钥的服务。您也可以定义不带包装密钥的密钥环,或者使用其他配置选项定义更复杂的密钥环。有关选择和使用 AWS Encryption SDK 定义的密钥环的帮助,请参阅 使用密钥环。C、C# /.NET 和版本 3 支持密钥环。 JavaScript 的 x 个AWS Encryption SDK for Java。

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

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

有关指定包装密钥的详细信息,请参阅 选择包装密钥

加密上下文

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

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

AWS Encryption SDK 使用的加密上下文包含您指定的加密上下文和加密材料管理器(CMM)添加的公有密钥对。具体来说,每当您使用带签名的加密算法时,CMM 都会向加密上下文(由保留名称、aws-crypto-public-key 和表示公有验证密钥的值组成)添加一个名称/值对。加密上下文中的 aws-crypto-public-key 名称被 AWS Encryption SDK保留,不能用作加密上下文中任何其他对中的名称。有关详细信息,请参阅“消息格式参考”中的 AAD

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

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

要解密数据,您可以传入加密的消息。AWS Encryption SDK可从加密的消息标头中提取加密上下文,因此您不需要另行提供加密上下文。但是,加密上下文可帮助您确认解密的是正确的加密消息。

  • AWS Encryption SDK命令行界面 (CLI) 中,如果您在 decrypt 命令中提供加密上下文,CLI 将在返回明文数据前验证加密消息的加密上下文中是否存在这些值。

  • 在其他编程语言实现中,解密响应包含加密上下文和明文数据。应用程序中的解密函数应始终在返回明文数据前验证解密响应中的加密上下文是否包含加密请求(或子集)中的加密上下文。

注意

使用版本 4。 .NET AWS Encryption SDK 的 x版本 3。 x 中 AWS Encryption SDK for Java,您可以使用所需的加密上下文 CMM 在所有加密请求中要求使用加密上下文。

在选择加密上下文时,请记住它不是机密的。加密上下文以明文形式显示在 AWS Encryption SDK 返回的加密的消息标头中。如果使用 AWS Key Management Service,加密上下文也可能以明文形式显示在审核记录和日志中,如 AWS CloudTrail。

有关在代码中提交和验证加密上下文的示例,请参阅您的首选编程语言示例。

加密的消息

在使用 AWS Encryption SDK加密数据时,它返回加密的消息。

加密的消息是一种可移植的格式化数据结构,包含加密的数据、数据密钥的加密副本、算法 ID 以及可选的加密上下文数字签名。AWS Encryption SDK中的加密操作返回加密的消息,解密操作将加密的消息作为输入。

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

有关加密的消息的技术信息,请参阅加密的消息格式

算法套件

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

AWS Encryption SDK将建议的算法套件指定为所有加密操作的默认套件。随着标准和最佳实践的不断改进,默认套件可能会发生变化。您可以在加密数据的请求中或在创建加密材料管理器(CMM)时指定备用算法套件,但除非您的环境需要使用备用套件,否则,最好使用默认套件。当前的默认值是 AES-GCM,具有基于 HMAC 的 extract-and-expand 密钥派生函数 (H KDF)、密钥承诺椭圆曲线数字签名算法 (ECDSA) 签名和 256 位加密密钥。

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

加密材料管理器

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

您可以使用 AWS Encryption SDK 提供的默认 CMM 或缓存 CMM,或者编写自定义 CMM。您可以指定 CMM,但这不是必需的。您指定密钥环或主密钥提供程序时,AWS Encryption SDK 将创建默认的 CMM。默认 CMM 从您指定的密钥环或主密钥提供程序获取加密或解密材料。这可能涉及调用一个加密服务,如 AWS Key Management Service (AWS KMS)。

由于 CMM 作为 AWS Encryption SDK 和密钥环(或主密钥提供程序)之间的联系纽带,因此,这是进行自定义和扩展的理想位置,例如,提供策略实施和缓存支持。AWS Encryption SDK提供缓存 CMM 以支持数据密钥缓存

对称加密和非对称加密

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

非对称加密使用数学相关的数据密钥对。密钥对中的一个密钥对数据进行加密;只有密钥对中的另一个密钥可以解密数据。有关详细信息,请参阅《AWS Cryptographic Services and Tools Guide》中的 Cryptographic algorithms

AWS Encryption SDK 使用信封加密。使用对称数据密钥加密您的数据。使用一个或多个对称或非对称包装密钥加密对称数据密钥。返回一条加密的消息,其中包含加密数据和至少一个数据密钥的加密副本。

加密数据(对称加密)

为加密您的数据,AWS Encryption SDK 使用对称数据密钥和包含对称加密算法的算法套件。为解密数据,AWS Encryption SDK 使用相同的数据密钥和相同的算法套件。

加密数据密钥(对称或非对称加密)

您为加密和解密操作提供的密钥环主密钥提供程序决定了对称数据密钥的加密和解密方式。您可以选择使用对称加密的密钥环或主密钥提供程序(例如 AWS KMS 密钥环),也可以选择使用非对称加密的密钥环或主密钥提供程序,例如原始 RSA 密钥环或 JceMasterKey

密钥承诺

AWS Encryption SDK 支持密钥承诺(有时称为可靠性),这是一种安全属性,可保证每个加密文字只能解密为单个明文。为此,密钥承诺可保证仅使用加密消息的数据密钥来解密消息。使用密钥承诺进行加密和解密是 AWS Encryption SDK 最佳实践

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

AWS Encryption SDK 始终使用一个唯一的数据密钥对每条明文消息进行加密。可能会使用多个包装密钥(或主密钥)加密该数据密钥,但包装密钥始终加密相同的数据密钥。尽管如此,手动制作的复杂加密的消息实际上可能包含不同的数据密钥,每个数据密钥都由不同的包装密钥加密。例如,如果一个用户对加密的消息进行解密,将返回 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 支持用于设置默认算法套件并限制可能使用的算法套件的承诺策略。此策略决定您的数据是否通过密钥承诺进行加密和解密。

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

有关迁移到版本 1.7.x 和 2.0.x 的更多信息,包括其密钥承诺功能,请参阅 迁移 AWS Encryption SDK。有关密钥承诺的技术信息,请参阅 AWS Encryption SDK 算法参考AWS Encryption SDK 消息格式参考

承诺策略

承诺策略是一种配置设置,用于确定您的应用程序是否使用密钥承诺进行加密和解密。使用密钥承诺进行加密和解密是 AWS Encryption SDK 最佳实践

承诺策略有三个值。

注意

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

承诺策略值
使用密钥承诺进行加密 不使用密钥承诺进行加密 使用密钥承诺进行解密 不使用密钥承诺进行解密
ForbidEncryptAllowDecrypt Red circle with white X inside, indicating prohibition or cancellation. Green checkmark icon indicating approval or confirmation. Green checkmark icon indicating approval or confirmation. Green checkmark icon indicating approval or confirmation.
RequireEncryptAllowDecrypt Green checkmark icon indicating approval or confirmation. Red circle with white X inside, indicating prohibition or cancellation. Green checkmark icon indicating approval or confirmation. Green checkmark icon indicating approval or confirmation.
RequireEncryptRequireDecrypt Green checkmark icon indicating approval or confirmation. Red circle with white X inside, indicating prohibition or cancellation. Green checkmark icon indicating approval or confirmation. Red circle with white X inside, indicating prohibition or cancellation.

AWS Encryption SDK 版本 1.7.x 中引入了承诺策略设置。该设置在所有支持的编程语言中都有效。

  • ForbidEncryptAllowDecrypt 使用或不使用密钥承诺进行解密,但不会使用密钥承诺进行加密。这是对版本 1.7.x 中承诺策略唯一的有效值,用于所有加密和解密操作。该值旨在让运行您的应用程序的所有主机在遇到使用密钥承诺加密的加密文字之前准备好使用密钥承诺进行解密。

  • RequireEncryptAllowDecrypt 始终使用密钥承诺进行加密。可以使用或不使用密钥承诺进行解密。此值在版本 2.0.x 中引入,允许您使用密钥承诺开始加密,但仍然可以不使用密钥承诺解密旧加密文字。

  • RequireEncryptRequireDecrypt 仅使用密钥承诺进行加密和解密。此值是版本 2.0.x 的默认值。当您确定所有加密文字都使用密钥承诺进行加密时,请使用此值。

承诺策略设置决定了您可以使用哪些算法套件。从版本 1.7.x 开始,AWS Encryption SDK 支持密钥承诺的算法套件;使用和不使用签名均可支持。如果您指定的算法套件与您的承诺策略冲突,则 AWS Encryption SDK 会返回错误。

有关设置承诺策略的帮助,请参阅 设置您的承诺策略

数字签名

为了确保数字消息在系统之间传输时的完整性,您可以对消息应用数字签名。数字签名始终是非对称的。您使用私有密钥创建签名,并将其附加到原始消息中。您的收件人使用公有密钥验证自您签名以来该消息是否未被修改。

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

为避免此问题,AWS Encryption SDK 支持在加密消息的末尾添加椭圆曲线数字签名算法(ECDSA)签名。使用签名算法套件时,AWS Encryption SDK 会为每条加密的消息生成临时私有密钥和公有密钥对。AWS Encryption SDK 将公有密钥存储在数据密钥的加密上下文中并丢弃私有密钥,任何人都无法创建其他使用公有密钥进行验证的签名。由于该算法将公有密钥绑定到加密的数据密钥作为消息标头中其他经过身份验证的数据,所以只能解密消息的用户无法更改公有密钥。

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