将现有 DynamoDB 表配置为使用适用于 DynamoDB AWS 的数据库加密 SDK - AWS 数据库加密 SDK

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

将现有 DynamoDB 表配置为使用适用于 DynamoDB AWS 的数据库加密 SDK

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

使用适用于 DynamoDB 的 Java 客户端加密库的 3.x 版本,您可以配置现有的 Amazon DynamoDB 表以进行客户端加密。本主题提供有关添加版本 3.x 到已填充的现有 DynamoDB 表要采取的三个步骤的指导。

先决条件

适用于 DynamoDB 的 Java 客户端加密库中的版本 3.x 需要 AWS SDK for Java 2.x 中提供的 DynamoDB 增强型客户端。如果您仍在使用 D ynamoDBMapper,则必须迁移 AWS SDK for Java 2.x 到才能使用 DynamoDB 增强型客户端。

按照从 AWS SDK for Java的版本 1.x 迁移到 2.x 的说明进行操作。

然后,按照说明开始使用 DynamoDB 增强版客户端。API

在将表配置为使用适用于 DynamoDB 的 Java 客户端加密库之前,您需要使用带注释的数据类生成 TableSchema,并且需要创建增强型客户端

步骤 1:准备读取和写入加密项目

完成以下步骤,为 AWS 数据库加密SDK客户端做好读取和写入加密项目的准备。部署以下更改后,您的客户端将继续读取和写入明文项目。它不会对写入表中的任何新项目进行加密或签名,但却能够在加密项目显示后立即对其进行解密。这些更改使得客户端为开始加密新项目做好准备。在继续执行下一步操作之前,必须将以下更改部署到每一个读取器。

1. 定义您的属性操作

更新带注释的数据类以包含属性操作,这些操作定义哪些属性值将被加密和签名,哪些将仅被签名,哪些将被忽略。

有关 DynamoDB 增强型客户端注释的更多指导,请参阅上 GitHub的 aws-database-encryption-sdk-dynamodb 存储库中的 SimpleClass.java

默认情况下,主键属性已签名但未加密(SIGN_ONLY),而所有其他属性均经过加密和签名(ENCRYPT_AND_SIGN)。要指定例外情况,请使用在适用于 DynamoDB 的 Java 客户端加密库中定义的加密注释。例如,如果您只想对某个特定属性进行签名,请使用 @DynamoDbEncryptionSignOnly 注释。如果要对特定属性进行签名并将其包含在加密上下文中,请使用@DynamoDbEncryptionSignAndIncludeInEncryptionContext注释。如果对特定属性既不要签名也不要加密(DO_NOTHING),请使用 @DynamoDbEncryptionDoNothing 注释。

注意

如果您指定了任何SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT属性,则分区和排序属性也必须是SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT。有关显示用于定义的注释的示例SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT,请参阅 SimpleClass4.java

有关注释的示例,请参阅 使用带注释的数据类

2. 定义从签名中将可以排除哪些属性

以下示例假设所有 DO_NOTHING 属性共享不同的前缀“:”,并使用该前缀定义允许的未签名属性。客户端将假设任何带有“:”前缀的属性名称都被排除在签名之外。有关更多信息,请参阅 Allowed unsigned attributes

final String unsignedAttrPrefix = ":";
3. 创建密钥环

以下示例创建一个 AWS KMS 密钥环。 AWS KMS 密钥环使用对称加密或非对称加密RSA AWS KMS keys 来生成、加密和解密数据密钥。

此示例使用CreateMrkMultiKeyring对称加密 AWS KMS KMS密钥创建密钥环。CreateAwsKmsMrkMultiKeyring 方法可确保密钥环能够正确处理单区域密钥和多区域密钥。

final MaterialProviders matProv = MaterialProviders.builder() .MaterialProvidersConfig(MaterialProvidersConfig.builder().build()) .build(); final CreateAwsKmsMrkMultiKeyringInput keyringInput = CreateAwsKmsMrkMultiKeyringInput.builder() .generator(kmsKeyId) .build(); final IKeyring kmsKeyring = matProv.CreateAwsKmsMrkMultiKeyring(keyringInput);
4. 定义 DynamoDB 表的加密配置

以下示例定义了一个 tableConfigs 映射,该映射表示此 DynamoDB 表的加密配置。

此示例将 DynamoDB 表名称指定为逻辑表名称。强烈建议您在首次定义加密配置时将 DynamoDB 表名指定为逻辑表名。有关更多信息,请参阅 DynamoD AWS B 数据库加密SDK中的加密配置

必须指定 FORCE_WRITE_PLAINTEXT_ALLOW_READ_PLAINTEXT 作为明文替代。此策略继续读取和写入明文项目,读取加密项目,并使客户端做好准备以写入加密项目。

final Map<String, DynamoDbTableEncryptionConfig> tableConfigs = new HashMap<>(); final DynamoDbTableEncryptionConfig config = DynamoDbTableEncryptionConfig.builder() .logicalTableName(ddbTableName) .partitionKeyName("partition_key") .sortKeyName("sort_key") .schemaOnEncrypt(tableSchema) .keyring(kmsKeyring) .allowedUnsignedAttributePrefix(unsignedAttrPrefix) .plaintextOverride(PlaintextOverride.FORCE_WRITE_PLAINTEXT_ALLOW_READ_PLAINTEXT) .build(); tableConfigs.put(ddbTableName, config);
5. 创建 DynamoDbEncryptionInterceptor

以下示例使用步骤 3 中的 tableConfigs 创建 DynamoDbEncryptionInterceptor

DynamoDbEncryptionInterceptor interceptor = DynamoDbEncryptionInterceptor.builder() .config(DynamoDbTablesEncryptionConfig.builder() .tableEncryptionConfigs(tableConfigs) .build()) .build();

步骤 2:写入已加密和签名项目

更新 DynamoDbEncryptionInterceptor 配置中的明文策略,以允许客户端写入已加密和签名的项目。部署好以下更改后,客户端将根据您在步骤 1 中配置的属性操作对新项目进行加密和签名。客户将能够读取明文项目以及已加密和签名的项目。

在继续执行步骤 3 之前,您必须对表格中所有现有的明文项目进行加密和签名。您无法运行单一指标或查询来快速加密您的现有明文项目。使用对您的系统最有意义的过程。例如,您可以使用异步过程,以缓慢扫描表,然后使用您定义的属性操作和加密配置重写项目。要识别表中的纯文本项目,我们建议扫描所有不包含aws_dbe_headaws_dbe_foot属性的项目,这些项目在加密和签名时 AWS 数据库加密SDK添加到项目中。

以下示例更新了步骤 1 中的表加密配置。您必须使用 FORBID_WRITE_PLAINTEXT_ALLOW_READ_PLAINTEXT 更新明文替代。该策略继续读取明文项目,但也会读取和写入加密项目。DynamoDbEncryptionInterceptor使用更新的内容创建一个新的tableConfigs

final Map<String, DynamoDbTableEncryptionConfig> tableConfigs = new HashMap<>(); final DynamoDbTableEncryptionConfig config = DynamoDbTableEncryptionConfig.builder() .logicalTableName(ddbTableName) .partitionKeyName("partition_key") .sortKeyName("sort_key") .schemaOnEncrypt(tableSchema) .keyring(kmsKeyring) .allowedUnsignedAttributePrefix(unsignedAttrPrefix) .plaintextOverride(PlaintextOverride.FORBID_WRITE_PLAINTEXT_ALLOW_READ_PLAINTEXT) .build(); tableConfigs.put(ddbTableName, config);

步骤 3:仅读取已加密和签名项目

在对所有项目进行加密和签名后,请更新 DynamoDbEncryptionInterceptor 配置中的明文替代,以便仅允许客户端读取和写入已加密和签名的项目。部署好以下更改后,客户端将根据您在步骤 1 中配置的属性操作对新项目进行加密和签名。客户只能够读取已加密和签名的项目。

以下示例更新了步骤 2 中的表加密配置。您可以使用 FORBID_WRITE_PLAINTEXT_FORBID_READ_PLAINTEXT 更新明文替代,也可以从配置中移除明文策略。默认情况下,客户端仅读取和写入已加密和签名的项目。DynamoDbEncryptionInterceptor使用更新的内容创建一个新的tableConfigs

final Map<String, DynamoDbTableEncryptionConfig> tableConfigs = new HashMap<>(); final DynamoDbTableEncryptionConfig config = DynamoDbTableEncryptionConfig.builder() .logicalTableName(ddbTableName) .partitionKeyName("partition_key") .sortKeyName("sort_key") .schemaOnEncrypt(tableSchema) .keyring(kmsKeyring) .allowedUnsignedAttributePrefix(unsignedAttrPrefix) // Optional: you can also remove the plaintext policy from your configuration .plaintextOverride(PlaintextOverride.FORBID_WRITE_PLAINTEXT_FORBID_READ_PLAINTEXT) .build(); tableConfigs.put(ddbTableName, config);