AWS KMS 钥匙圈 - AWS 数据库加密 SDK

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

AWS KMS 钥匙圈

我们的客户端加密库已重命名为 AWS 数据库加密 SDK。本开发人员指南仍提供有关 DynamoDB 加密客户端的信息。

AWS KMS 密钥环使用对称加密或非对称 RSA AWS KMS keys来生成、加密和解密数据密钥。 AWS Key Management Service (AWS KMS) 保护您的 KMS 密钥并在 FIPS 边界内执行加密操作。我们建议您尽可能使用 AWS KMS 密钥环或具有类似安全属性的密钥环。

您还可以在密钥环中使用对称多区域 KMS 密钥。 AWS KMS 有关使用多区域的更多详细信息和示例 AWS KMS keys,请参阅使用多区域 AWS KMS keys。有关多区域密钥的信息,请参阅《AWS Key Management Service 开发人员指南》中的使用多区域密钥

AWS KMS 钥匙圈可以包括两种类型的包装钥匙:

  • 生成器密钥:生成并加密明文数据密钥。加密数据的密钥环必须有一个生成器密钥。

  • 其他密钥:加密生成器密钥生成的纯文本数据密钥。 AWS KMS 钥匙圈可以有零个或多个额外的钥匙。

您必须拥有生成器密钥才能加密记录。当 AWS KMS 密钥环只有一个 AWS KMS 密钥时,该密钥用于生成和加密数据密钥。

像所有钥匙圈一样, AWS KMS 钥匙圈可以单独使用,也可以与其他相同或不同类型的钥匙圈一起在多钥匙圈中使用。

AWS KMS 密钥环所需权限

AWS 数据库加密 SDK 不需要 AWS 账户 ,也不依赖于任何一个 AWS 服务。但是,要使用 AWS KMS 密钥环,您需要对 AWS 账户 密钥环 AWS KMS keys 中的具有以下最低权限。

有关权限的详细信息 AWS KMS keys,请参阅《AWS Key Management Service 开发人员指南》中的身份验证和访问控制

在 AWS KMS 钥匙圈 AWS KMS keys 中识别

一个 AWS KMS 钥匙圈可以包括一个或多 AWS KMS keys个。要在 AWS KMS 密钥环 AWS KMS key 中指定,请使用支持的 AWS KMS 密钥标识符。可用于在密钥环 AWS KMS key 中识别的密钥标识符因操作和语言实现而异。有关 AWS KMS key密钥标识符的详细信息,请参阅《AWS Key Management Service 开发人员指南》中的密钥标识符

作为最佳实践,请使用最适合您任务的密钥标识符。

  • 要使用密 AWS KMS 钥环进行加密,您可以使用密钥 ID、密钥 ARN 、别名或别名 ARN 来加密数据。

    注意

    如果您在加密密钥环中为 KMS 密钥指定别名名称或别名 ARN,则加密操作会将当前与该别名关联的密钥 ARN 保存在加密数据密钥的元数据中。它不会保存别名。更改别名不会影响用于解密加密数据密钥的 KMS 密钥。

  • 要使用密 AWS KMS 钥环解密,必须使用密钥 ARN 进行识别。 AWS KMS keys有关更多信息,请参阅 选择包装密钥

  • 在用于加密和解密的密钥环中,您必须使用密钥 ARN 以标识 AWS KMS keys。

解密时, AWS 数据库加密 SDK 会在密 AWS KMS 钥环中搜索 AWS KMS key 可以解密其中一个加密数据密钥的。具体而言, AWS 数据库加密 SDK 对材料描述中的每个加密数据密钥使用以下模式。

  • AWS 数据库加密 SDK 从材料描述的元数据 AWS KMS key 中获取加密数据密钥的密钥 ARN。

  • AWS 数据库加密 SDK 在解密密钥环中搜索密钥匹配的 AWS KMS key ARN。

  • 如果在密钥环中找到密钥 ARN 匹配的,则 AWS 数据库加密 SDK 会要求 AWS KMS 使用 KMS 密钥解密加密的数据密钥。 AWS KMS key

  • 否则,它跳到下一个加密的数据密钥(如果有)。

创建密 AWS KMS 钥环

您可以为每个 AWS KMS 密钥环配置一个 AWS KMS key 或多个 AWS KMS keys 相同或不同的密钥环 AWS 账户 。 AWS 区域 AWS KMS key 必须是对称加密密钥(SYMMETRIC_DEFAULT)或非对称 RSA KMS 密钥。您也可以使用对称加密多区域 KMS 密钥。您可以在多 AWS KMS密钥环中使用一个或多个钥匙圈。

您可以创建用于加密和解密数据的密 AWS KMS 钥环,也可以创建专门用于加密或解密的 AWS KMS 密钥环。创建用于加密数据的 AWS KMS 密钥环时,必须指定生成器密钥,该密钥用于生成纯文本数据密钥并对其进行加密。 AWS KMS key 数据密钥在数学上与 KMS 密钥无关。然后,如果您愿意,则可以指定用于加密相同纯文本数据密钥的其他 AWS KMS keys 内容。要解密受此密钥环保护的加密字段,您使用的解密密钥环必须至少包含密钥环中 AWS KMS keys 定义的密钥环中的一个,或者不是。 AWS KMS keys(没有的 AWS KMS 密钥环 AWS KMS keys 称为AWS KMS 发现密钥环。)

加密密钥环或多重密钥环中的所有包装密钥均必须能够加密数据密钥。如有任何包装密钥无法加密,此加密方法将失败。因此,调用方必须拥有密钥环中所有密钥的所需权限。如果您单独或在多重密钥环中使用 Discovery 密钥环加密数据,加密操作将失败。

以下示例使用该CreateAwsKmsMrkMultiKeyring方法创建具有对称加密 KMS AWS KMS 密钥的密钥环。该CreateAwsKmsMrkMultiKeyring方法会自动创建 AWS KMS 客户端,并确保密钥环能够正确处理单区域和多区域密钥。这些示例使用密钥 ARN 来识别 KMS 密钥。有关详细信息,请参阅 在 AWS KMS 钥匙圈 AWS KMS keys 中识别

Java
final MaterialProviders matProv = MaterialProviders.builder() .MaterialProvidersConfig(MaterialProvidersConfig.builder().build()) .build(); final CreateAwsKmsMrkMultiKeyringInput keyringInput = CreateAwsKmsMrkMultiKeyringInput.builder() .generator(kmsKeyArn) .build(); final IKeyring kmsKeyring = matProv.CreateAwsKmsMrkMultiKeyring(keyringInput);
C# / .NET
var matProv = new MaterialProviders(new MaterialProvidersConfig()); var createAwsKmsMrkMultiKeyringInput = new CreateAwsKmsMrkMultiKeyringInput { Generator = kmsKeyArn }; var awsKmsMrkMultiKeyring = matProv.CreateAwsKmsMrkMultiKeyring(createAwsKmsMrkMultiKeyringInput);

以下示例使用该CreateAwsKmsRsaKeyring方法创建带有非对称 RSA KMS AWS KMS 密钥的密钥环。要创建非对称 RSA AWS KMS 密钥环,请提供以下值。

  • kmsClient: 创建新 AWS KMS 客户端

  • kmsKeyID: 用于识别您的非对称 RSA KMS 密钥的密钥 ARN

  • publicKey: a 来 ByteBuffer 自 UTF-8 编码的 PEM 文件,该文件代表你传递给的密钥的公钥 kmsKeyID

  • encryptionAlgorithm: 加密算法必须是RSAES_OAEP_SHA_256RSAES_OAEP_SHA_1

Java
final MaterialProviders matProv = MaterialProviders.builder() .MaterialProvidersConfig(MaterialProvidersConfig.builder().build()) .build(); final CreateAwsKmsRsaKeyringInput createAwsKmsRsaKeyringInput = CreateAwsKmsRsaKeyringInput.builder() .kmsClient(KmsClient.create()) .kmsKeyId(rsaKMSKeyArn) .publicKey(publicKey) .encryptionAlgorithm(EncryptionAlgorithmSpec.RSAES_OAEP_SHA_256) .build(); IKeyring awsKmsRsaKeyring = matProv.CreateAwsKmsRsaKeyring(createAwsKmsRsaKeyringInput);
C# / .NET
var matProv = new MaterialProviders(new MaterialProvidersConfig()); var createAwsKmsRsaKeyringInput = new CreateAwsKmsRsaKeyringInput { KmsClient = new AmazonKeyManagementServiceClient(), KmsKeyId = rsaKMSKeyArn, PublicKey = publicKey, EncryptionAlgorithm = EncryptionAlgorithmSpec.RSAES_OAEP_SHA_256 }; IKeyring awsKmsRsaKeyring = matProv.CreateAwsKmsRsaKeyring(createAwsKmsRsaKeyringInput);

使用多区域 AWS KMS keys

您可以在 AWS 数据库加密 SDK 中使用多区域 AWS KMS keys 作为包装密钥。如果您使用多区域密钥合而为一进行加密 AWS 区域,则可以使用其他密钥中的相关多区域密钥进行解密。 AWS 区域

多区域 KMS 密钥是一组 AWS KMS keys AWS 区域 具有相同密钥材料和密钥 ID 的不同密钥。您可以像在不同区域使用相同的密钥一样使用这些相关密钥。多区域密钥支持常见的灾难恢复和备份场景,这些场景要求在一个区域进行加密,并在另一个区域进行解密,而无需进行跨区域调用。 AWS KMS有关多区域密钥的信息,请参阅《AWS Key Management Service 开发人员指南》中的使用多区域密钥

为了支持多区域密钥, AWS 数据库加密 SDK 包括支持 AWS KMS 多区域的密钥环。CreateAwsKmsMrkMultiKeyring 方法同时支持单区域密钥和多区域密钥。

  • 对于单区域密钥,支持多区域的符号的行为就像单区域 AWS KMS 密钥环一样。该密钥尝试仅使用加密数据的单区域密钥来解密加密文字。为了简化您的 AWS KMS 密钥环体验,我们建议您在使用对称加密 KMS 密钥时使用该CreateAwsKmsMrkMultiKeyring方法。

  • 对于多区域密钥,支持多区域的符号尝试使用加密数据的相同多区域密钥或您指定的区域中的相关多区域密钥来解密加密文字。

在使用多个 KMS 密钥的支持多区域的密钥环,您可以指定多个单区域和多区域密钥。但是,您只能在每组相关的多区域密钥中指定一个密钥。如果您使用相同的密钥 ID 指定多个密钥标识符,则构造函数调用将失败。

以下示例使用多区域 KMS AWS KMS 密钥创建密钥环。这些示例将多区域密钥指定为生成器密钥,将单区域密钥指定为子密钥。

Java
final MaterialProviders matProv = MaterialProviders.builder() .MaterialProvidersConfig(MaterialProvidersConfig.builder().build()) .build(); final CreateAwsKmsMrkMultiKeyringInput createAwsKmsMrkMultiKeyringInput = CreateAwsKmsMrkMultiKeyringInput.builder() .generator(multiRegionKeyArn) .kmsKeyIds(Collections.singletonList(kmsKeyArn)) .build(); IKeyring awsKmsMrkMultiKeyring = matProv.CreateAwsKmsMrkMultiKeyring(createAwsKmsMrkMultiKeyringInput);
C# / .NET
var matProv = new MaterialProviders(new MaterialProvidersConfig()); var createAwsKmsMrkMultiKeyringInput = new CreateAwsKmsMrkMultiKeyringInput { Generator = multiRegionKeyArn, KmsKeyIds = new List<String> { kmsKeyArn } }; var awsKmsMrkMultiKeyring = matProv.CreateAwsKmsMrkMultiKeyring(createAwsKmsMrkMultiKeyringInput);

使用多区域 AWS KMS 密钥环时,可以在严格模式或发现模式下解密密文。要在严格模式下解密加密文字,请使用您解密加密文字的区域中相关多区域密钥的密钥 ARN 来实例化支持多区域的符号。如果您在其他区域(例如,加密记录所在的区域)中指定相关多区域密钥的密钥 ARN,则支持多区域的符号将为该 AWS KMS key发出跨区域调用。

在严格模式下解密时,支持多区域的符号需要密钥 ARN。仅接受每组相关的多区域密钥中的一个密钥 ARN。

您还可以在发现模式下使用 AWS KMS 多区域密钥进行解密。在发现模式下解密时,不需指定任何 AWS KMS keys。(有关单区域 AWS KMS 发现密钥环的信息,请参阅使用 AWS KMS 发现密钥环。)

如果您使用多区域密钥加密,则发现模式下支持多区域的符号将尝试使用本地区域中的相关多区域密钥进行解密。如果不存在,则调用失败。在发现模式下, AWS 数据库加密 SDK 不会尝试跨区域调用用于加密的多区域密钥。

使用 AWS KMS 发现密钥环

解密时,最佳做法是指定 AWS 数据库加密 SDK 可以使用的包装密钥。要遵循此最佳实践,请使用 AWS KMS 解密密钥环,将 AWS KMS 封装密钥限制在您指定的密钥范围内。但是,您也可以创建AWS KMS 发现密钥环,即不指定任何包装 AWS KMS 密钥的密钥环。

AWS 数据库加密 SDK 为 AWS KMS 多区域密钥提供了标准 AWS KMS 发现密钥环和发现密钥环。有关多区域密钥与 AWS 数据库加密 SDK 结合使用的信息,请参阅 使用多区域 AWS KMS keys

由于 Discovery 密钥环未指定任何包装密钥,因此 Discovery 密钥无法加密数据。如果您单独或在多重密钥环中使用 Discovery 密钥环加密数据,加密操作将失败。

解密时,发现密钥环允许 AWS 数据库加密 SDK 要求使用加密数据密钥 AWS KMS 来解密任何加密的数据密钥,无论谁拥有或有权访问该 AWS KMS key 密钥。 AWS KMS key只有在调用方拥有 AWS KMS key的 kms:Decrypt 权限时,调用才会成功。

重要

如果您在解密多密钥环中包含 AWS KMS 发现密钥环,则发现密钥环将覆盖多密钥环中其他密钥环中指定的所有 KMS 密钥限制。多重密钥环的行为类似于限制最少的密钥环。如果您单独或在多重密钥环中使用 Discovery 密钥环加密数据,加密操作将失败

为方便起见, AWS 数据库加密 SDK 提供了 AWS KMS 发现密钥环。不过,出于以下原因,建议尽可能使用更受限制的密钥环。

  • 真实性 — AWS KMS 发现密钥环可以使用任何 AWS KMS key 用于加密材料描述中的数据密钥的密钥,前提是调用者有权使用该密钥 AWS KMS key 进行解密。这可能不是呼叫 AWS KMS key 者打算使用的。例如,其中一个加密的数据密钥可能是在任何人都可以 AWS KMS key 使用的安全性较低的情况下加密的。

  • 延迟和性能 — AWS KMS 发现密钥环可能比其他密钥环慢得多,因为 AWS 数据库加密 SDK 会尝试解密所有加密的数据密钥,包括由 AWS KMS keys 其他 AWS 账户 和区域加密的数据密钥,而调用者无权使用这些密钥进行解密。 AWS KMS keys

如果您使用发现密钥环,我们建议您使用发现过滤器将可用的 KMS 密钥限制为指定 AWS 账户 和分区中的密钥。如需帮助查找您的账户 ID 和分区,请参阅中的您的 AWS 账户 标识符ARN 格式AWS 一般参考

以下代码示例使用发现过滤器实例化 AWS KMS 发现密钥环,该过滤器将 AWS 数据库加密 SDK 可以使用的 KMS 密钥限制为aws分区和111122223333示例账户中的密钥。

在使用此代码之前,请将示例 AWS 账户 和分区值替换为 AWS 账户 和分区的有效值。如果您的 KMS 密钥位于中国区域,请使用 aws-cn 分区值。如果您的 KMS 密钥位于 AWS GovCloud (US) Regions,请使用 aws-us-gov 分区值。对于所有其他 AWS 区域,请使用 aws 分区值。

Java
// Create discovery filter DiscoveryFilter discoveryFilter = DiscoveryFilter.builder() .partition("aws") .accountIds(111122223333) .build(); // Create the discovery keyring CreateAwsKmsMrkDiscoveryMultiKeyringInput createAwsKmsMrkDiscoveryMultiKeyringInput = CreateAwsKmsMrkDiscoveryMultiKeyringInput.builder() .discoveryFilter(discoveryFilter) .build(); IKeyring decryptKeyring = matProv.CreateAwsKmsMrkDiscoveryMultiKeyring(createAwsKmsMrkDiscoveryMultiKeyringInput);
C# / .NET
// Create discovery filter var discoveryFilter = new DiscoveryFilter { Partition = "aws", AccountIds = 111122223333 }; // Create the discovery keyring var createAwsKmsMrkDiscoveryMultiKeyringInput = new CreateAwsKmsMrkDiscoveryMultiKeyringInput { DiscoveryFilter = discoveryFilter }; var decryptKeyring = matProv.CreateAwsKmsMrkDiscoveryMultiKeyring(createAwsKmsMrkDiscoveryMultiKeyringInput);

使用 AWS KMS 区域发现密钥环

AWS KMS Regional Discovery 密钥环是一种不指定 KMS 密钥 ARN 的密钥环。相反,它允许 AWS 数据库加密 SDK 仅使用 KMS 密钥进行解密。 AWS 区域

使用 AWS KMS 区域发现密钥环解密时, AWS 数据库加密 SDK 会解密在指定项下加密的所有加密数据密钥。 AWS KMS key AWS 区域要成功,调用者必须拥有对数据密钥 AWS KMS keys 中至少一个加密数据密钥 AWS 区域 的kms:Decrypt权限。

与其他 Discovery 密钥环相同,Regional Discovery 密钥环对加密无效。该密钥环仅在解密加密字段时适用。如果您在用于加密和解密的多重密钥环中使用 Regional Discovery 密钥环,则该密钥环仅在解密时有效。如果您单独或在多重密钥环中使用多区域 Discovery 密钥环加密数据,加密操作将失败。

重要

如果您在解密多密钥环中包含 AWS KMS 区域发现密钥环,则区域发现密钥环将覆盖多密钥环中其他密钥环中指定的所有 KMS 密钥限制。多重密钥环的行为类似于限制最少的密钥环。单独使用或在多重密钥环中使用时, AWS KMS Discovery 密钥环对加密无效。

AWS 数据库加密 SDK 中的区域发现密钥环仅尝试使用指定区域中的 KMS 密钥进行解密。使用发现密钥环时,需要在 AWS KMS 客户端上配置区域。这些 AWS 数据库加密 SDK 实现不会按区域筛选 KMS 密钥,但对指定区域之外的 KMS 密钥的解密请求 AWS KMS 将失败。

如果您使用发现密钥环,我们建议您使用发现过滤器将解密中使用的 KMS 密钥限制为指定 AWS 账户 和分区中的密钥。

例如,以下代码使用发现过滤器创建 AWS KMS 区域发现密钥环。此密钥环将 AWS 数据库加密 SDK 限制为美国西部(俄勒冈)区域 (us-west-2) 账户 111122223333 中的 KMS 密钥。

Java
// Create the discovery filter DiscoveryFilter discoveryFilter = DiscoveryFilter.builder() .partition("aws") .accountIds(111122223333) .build(); // Create the discovery keyring CreateAwsKmsMrkDiscoveryMultiKeyringInput createAwsKmsMrkDiscoveryMultiKeyringInput = CreateAwsKmsMrkDiscoveryMultiKeyringInput.builder() .discoveryFilter(discoveryFilter) .regions("us-west-2") .build(); IKeyring decryptKeyring = matProv.CreateAwsKmsMrkDiscoveryMultiKeyring(createAwsKmsMrkDiscoveryMultiKeyringInput);
C# / .NET
// Create discovery filter var discoveryFilter = new DiscoveryFilter { Partition = "aws", AccountIds = 111122223333 }; // Create the discovery keyring var createAwsKmsMrkDiscoveryMultiKeyringInput = new CreateAwsKmsMrkDiscoveryMultiKeyringInput { DiscoveryFilter = discoveryFilter, Regions = us-west-2 }; var decryptKeyring = matProv.CreateAwsKmsMrkDiscoveryMultiKeyring(createAwsKmsMrkDiscoveryMultiKeyringInput);