本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
迁移到适用于 DynamoDB 的 Java 客户端加密库的版本 3.x
我们的客户端加密库已重命名为 AWS 数据库加密 SDK。本开发人员指南仍提供有关 DynamoDB 加密客户端的信息。 |
适用于 DynamoDB 的 Java 客户端加密库的版本 3.x 是对 2.x 代码库的重大改写。它包括许多更新,例如新的结构化数据格式、改进的多租户支持、无缝架构更改,以及可搜索的加密支持。本主题提供有关如何将代码迁移到版本 3.x 的指导。
从版本 1.x 迁移到 2.x
在迁移到版本 3.x 之前先迁移到版本 2.x。版本 2.x 已将最新提供程序的符号从 MostRecentProvider
更改为 CachingMostRecentProvider
。如果您当前使用的是带有 MostRecentProvider
符号的适用于 DynamoDB 的 Java 客户端加密库的版本 1.x,必须将代码中的符号名称更新为 CachingMostRecentProvider
。要了解更多信息,请参阅最新提供程序的更新。
从版本 2.x 迁移到 3.x
以下步骤说明如何将您的代码从适用于 DynamoDB 的 Java 客户端加密库的版本 2.x 迁移到版本 3.x。
第 1 步。准备读取新格式的项目
完成以下步骤,准备您的 AWS 数据库加密 SDK 客户端,以读取新格式的项目。部署以下更改后,您的客户端将继续以与版本 2.x 相同的行为方式运行。您的客户将继续读取和写入 2.x 格式中的项目,但是这些更改使客户端做好读取新格式项目的准备。
- 将你的版本更新 AWS SDK for Java 到 2.x 版
-
适用于 DynamoDB 的 Java 客户端加密库的版本 3.x 需要 DynamoDB 增强型客户端。DynamoDB 增强版客户端将取代先前版本中使用的 DynamoDBMapper。要使用增强型客户端,您必须使用 AWS SDK for Java 2.x。
按照从 AWS SDK for Java的版本 1.x 迁移到 2.x 的说明进行操作。
有关需要哪些 AWS SDK for Java 2.x 模块的更多信息,请参阅先决条件。
- 配置您的客户端,以读取由旧版本加密的项目
-
以下过程概述了以下代码示例中所演示的步骤。
-
创建一个密钥环。
密钥环和加密材料管理程序将取代以前版本的适用于 DynamoDB 的 Java 客户端加密库中使用的加密材料提供程序。
重要
您在创建密钥环时指定的包装密钥必须与版本 2.x 中用于加密材料提供程序的包装密钥相同。
-
创建一个带注释的类的表架构。
此步骤用于定义开始以新格式编写项目时将使用的属性操作。
有关使用全新 DynamoDB 增强版客户端的指南,请参阅《AWS SDK for Java 开发人员指南》中的生成一个
TableSchema
。以下示例假设您已使用新的属性操作注释从版本 2.x 中更新您的带注释类。有关为属性操作添加注释的更多指导,请参阅 使用带注释的数据类。
注意
如果您指定了任何
SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT
属性,则分区和排序属性也必须是SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT
。有关显示用于定义的注释的示例SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT
,请参阅 SimpleClass4.java。 -
定义从签名中可以排除哪些属性。
-
配置在 2.x 版本建模类中配置的属性操作的显式映射。
此步骤定义用于以旧格式编写项目的属性操作。
-
配置
DynamoDBEncryptor
您在适用于 DynamoDB 的 Java 客户端加密库的版本 2.x 中使用的 。 -
配置遗留行为。
-
创建
DynamoDbEncryptionInterceptor
。 -
创建一个新的 AWS SDK DynamoDB 客户端。
-
创建
DynamoDBEnhancedClient
并使用您的建模类创建表。要了解 DynamoDB 增强版客户端的更多信息,请参阅创建增强型客户端。
-
public class MigrationExampleStep1 { public static void MigrationStep1(String kmsKeyId, String ddbTableName, int sortReadValue) { // 1. Create a Keyring. // This example creates an AWS KMS Keyring that specifies the // same kmsKeyId previously used in the version 2.x configuration. // It uses the 'CreateMrkMultiKeyring' method to create the // keyring, so that the keyring can correctly handle both single // region and Multi-Region KMS Keys. // Note that this example uses the AWS SDK for Java v2 KMS client. final MaterialProviders matProv = MaterialProviders.builder() .MaterialProvidersConfig(MaterialProvidersConfig.builder().build()) .build(); final CreateAwsKmsMrkMultiKeyringInput keyringInput = CreateAwsKmsMrkMultiKeyringInput.builder() .generator(
kmsKeyId
) .build(); final IKeyring kmsKeyring = matProv.CreateAwsKmsMrkMultiKeyring(keyringInput); // 2. Create a Table Schema over your annotated class. // For guidance on using the new attribute actions // annotations, see SimpleClass.java in the // aws-database-encryption-sdk-dynamodb GitHub repository. // All primary key attributes must be signed but not encrypted // and by default all non-primary key attributes // are encrypted and signed (ENCRYPT_AND_SIGN). // If you want a particular non-primary key attribute to be signed but // not encrypted, use the 'DynamoDbEncryptionSignOnly' annotation. // If you want a particular attribute to be neither signed nor encrypted // (DO_NOTHING), use the 'DynamoDbEncryptionDoNothing' annotation. final TableSchema<SimpleClass> schemaOnEncrypt = TableSchema.fromBean(SimpleClass.class); // 3. Define which attributes the client should expect to be excluded // from the signature when reading items. // This value represents all unsigned attributes across the entire // dataset. final List<String> allowedUnsignedAttributes = Arrays.asList("attribute3"); // 4. Configure an explicit map of the attribute actions configured // in your version 2.x modeled class. final Map<String, CryptoAction> legacyActions = new HashMap<>(); legacyActions.put("partition_key
", CryptoAction.SIGN_ONLY); legacyActions.put("sort_key
", CryptoAction.SIGN_ONLY); legacyActions.put("attribute1
", CryptoAction.ENCRYPT_AND_SIGN); legacyActions.put("attribute2
", CryptoAction.SIGN_ONLY); legacyActions.put("attribute3
", CryptoAction.DO_NOTHING); // 5. Configure the DynamoDBEncryptor that you used in version 2.x. final AWSKMS kmsClient = AWSKMSClientBuilder.defaultClient(); final DirectKmsMaterialProvider cmp = new DirectKmsMaterialProvider(kmsClient, kmsKeyId); final DynamoDBEncryptor oldEncryptor = DynamoDBEncryptor.getInstance(cmp); // 6. Configure the legacy behavior. // Input the DynamoDBEncryptor and attribute actions created in // the previous steps. For Legacy Policy, use // 'FORCE_LEGACY_ENCRYPT_ALLOW_LEGACY_DECRYPT'. This policy continues to read // and write items using the old format, but will be able to read // items written in the new format as soon as they appear. final LegacyOverride legacyOverride = LegacyOverride .builder() .encryptor(oldEncryptor) .policy(LegacyPolicy.FORCE_LEGACY_ENCRYPT_ALLOW_LEGACY_DECRYPT) .attributeActionsOnEncrypt(legacyActions) .build(); // 7. Create a DynamoDbEncryptionInterceptor with the above configuration. final Map<String, DynamoDbEnhancedTableEncryptionConfig> tableConfigs = new HashMap<>(); tableConfigs.put(ddbTableName, DynamoDbEnhancedTableEncryptionConfig.builder() .logicalTableName(ddbTableName
) .keyring(kmsKeyring
) .allowedUnsignedAttributes(allowedUnsignedAttributes) .schemaOnEncrypt(tableSchema) .legacyOverride(legacyOverride) .build()); final DynamoDbEncryptionInterceptor interceptor = DynamoDbEnhancedClientEncryption.CreateDynamoDbEncryptionInterceptor( CreateDynamoDbEncryptionInterceptorInput.builder() .tableEncryptionConfigs(tableConfigs) .build() ); // 8. Create a new AWS SDK DynamoDb client using the // interceptor from Step 7. final DynamoDbClient ddb = DynamoDbClient.builder() .overrideConfiguration( ClientOverrideConfiguration.builder() .addExecutionInterceptor(interceptor) .build()) .build(); // 9. Create the DynamoDbEnhancedClient using the AWS SDK DynamoDb client // created in Step 8, and create a table with your modeled class. final DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder() .dynamoDbClient(ddb) .build(); final DynamoDbTable<SimpleClass> table = enhancedClient.table(ddbTableName, tableSchema); } }
第 2 步。用新格式编写项目
将步骤 1 中的更改部署到所有读取器后,请完成以下步骤,将 AWS 数据库加密 SDK 客户端配置为以新格式写入项目。部署以下更改后,您的客户端将继续读取旧格式的项目,并且开始以新格式编写和读取项目。
以下过程概述了以下代码示例中所演示的步骤。
public class MigrationExampleStep2 { public static void MigrationStep2(String kmsKeyId, String ddbTableName, int sortReadValue) { // 1. Continue to configure your keyring, table schema, legacy // attribute actions, allowedUnsignedAttributes, and // DynamoDBEncryptor as you did in Step 1. final MaterialProviders matProv = MaterialProviders.builder() .MaterialProvidersConfig(MaterialProvidersConfig.builder().build()) .build(); final CreateAwsKmsMrkMultiKeyringInput keyringInput = CreateAwsKmsMrkMultiKeyringInput.builder() .generator(
kmsKeyId
) .build(); final IKeyring kmsKeyring = matProv.CreateAwsKmsMrkMultiKeyring(keyringInput); final TableSchema<SimpleClass> schemaOnEncrypt = TableSchema.fromBean(SimpleClass.class); final List<String> allowedUnsignedAttributes = Arrays.asList("attribute3"); final Map<String, CryptoAction> legacyActions = new HashMap<>(); legacyActions.put("partition_key
", CryptoAction.SIGN_ONLY); legacyActions.put("sort_key
", CryptoAction.SIGN_ONLY); legacyActions.put("attribute1
", CryptoAction.ENCRYPT_AND_SIGN); legacyActions.put("attribute2
", CryptoAction.SIGN_ONLY); legacyActions.put("attribute3
", CryptoAction.DO_NOTHING); final AWSKMS kmsClient = AWSKMSClientBuilder.defaultClient(); final DirectKmsMaterialProvider cmp = new DirectKmsMaterialProvider(kmsClient, kmsKeyId); final DynamoDBEncryptor oldEncryptor = DynamoDBEncryptor.getInstance(cmp); // 2. Update your legacy behavior to only write new items using the new // format. // For Legacy Policy, use 'FORBID_LEGACY_ENCRYPT_ALLOW_LEGACY_DECRYPT'. This policy // continues to read items in both formats, but will only write items // using the new format. final LegacyOverride legacyOverride = LegacyOverride .builder() .encryptor(oldEncryptor) .policy(LegacyPolicy.FORBID_LEGACY_ENCRYPT_ALLOW_LEGACY_DECRYPT) .attributeActionsOnEncrypt(legacyActions) .build(); // 3. Create a DynamoDbEncryptionInterceptor with the above configuration. final Map<String, DynamoDbEnhancedTableEncryptionConfig> tableConfigs = new HashMap<>(); tableConfigs.put(ddbTableName, DynamoDbEnhancedTableEncryptionConfig.builder() .logicalTableName(ddbTableName
) .keyring(kmsKeyring
) .allowedUnsignedAttributes(allowedUnsignedAttributes) .schemaOnEncrypt(tableSchema) .legacyOverride(legacyOverride) .build()); final DynamoDbEncryptionInterceptor interceptor = DynamoDbEnhancedClientEncryption.CreateDynamoDbEncryptionInterceptor( CreateDynamoDbEncryptionInterceptorInput.builder() .tableEncryptionConfigs(tableConfigs) .build() ); // 4. Create a new AWS SDK DynamoDb client using the // interceptor from Step 3. final DynamoDbClient ddb = DynamoDbClient.builder() .overrideConfiguration( ClientOverrideConfiguration.builder() .addExecutionInterceptor(interceptor) .build()) .build(); // 5. Create the DynamoDbEnhancedClient using the AWS SDK DynamoDb Client created // in Step 4, and create a table with your modeled class. final DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder() .dynamoDbClient(ddb) .build(); final DynamoDbTable<SimpleClass> table = enhancedClient.table(ddbTableName, tableSchema); } }
部署步骤 2 的更改后,必须使用新格式重新加密表中的所有旧项目,然后才能继续执行步骤 3。您无法运行单一指标或查询来快速加密您的现有项目。使用对您的系统最有意义的过程。例如,您可以使用异步过程,以缓慢扫描表,然后使用您定义的新属性操作和加密配置重写项目。
第 3 步。只能以新格式读取和编写项目
使用新格式重新加密表格中的所有项目后,您可以从配置中移除遗留行为。完成以下步骤以将客户端配置为仅以新格式读取和编写项目。
以下过程概述了以下代码示例中所演示的步骤。
public class MigrationExampleStep3 { public static void MigrationStep3(String kmsKeyId, String ddbTableName, int sortReadValue) { // 1. Continue to configure your keyring, table schema, // and allowedUnsignedAttributes as you did in Step 1. // Do not include the configurations for the DynamoDBEncryptor or // the legacy attribute actions. final MaterialProviders matProv = MaterialProviders.builder() .MaterialProvidersConfig(MaterialProvidersConfig.builder().build()) .build(); final CreateAwsKmsMrkMultiKeyringInput keyringInput = CreateAwsKmsMrkMultiKeyringInput.builder() .generator(
kmsKeyId
) .build(); final IKeyring kmsKeyring = matProv.CreateAwsKmsMrkMultiKeyring(keyringInput); final TableSchema<SimpleClass> schemaOnEncrypt = TableSchema.fromBean(SimpleClass.class); final List<String> allowedUnsignedAttributes = Arrays.asList("attribute3"); // 3. Create a DynamoDbEncryptionInterceptor with the above configuration. // Do not configure any legacy behavior. final Map<String, DynamoDbEnhancedTableEncryptionConfig> tableConfigs = new HashMap<>(); tableConfigs.put(ddbTableName, DynamoDbEnhancedTableEncryptionConfig.builder() .logicalTableName(ddbTableName
) .keyring(kmsKeyring
) .allowedUnsignedAttributes(allowedUnsignedAttributes) .schemaOnEncrypt(tableSchema) .build()); final DynamoDbEncryptionInterceptor interceptor = DynamoDbEnhancedClientEncryption.CreateDynamoDbEncryptionInterceptor( CreateDynamoDbEncryptionInterceptorInput.builder() .tableEncryptionConfigs(tableConfigs) .build() ); // 4. Create a new AWS SDK DynamoDb client using the // interceptor from Step 3. final DynamoDbClient ddb = DynamoDbClient.builder() .overrideConfiguration( ClientOverrideConfiguration.builder() .addExecutionInterceptor(interceptor) .build()) .build(); // 5. Create the DynamoDbEnhancedClient using the AWS SDK Client // created in Step 4, and create a table with your modeled class. final DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder() .dynamoDbClient(ddb) .build(); final DynamoDbTable<SimpleClass> table = enhancedClient.table(ddbTableName, tableSchema); } }