

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# DynamoDB용 Java 클라이언트측 암호화 라이브러리 버전 3.x로 마이그레이션
<a name="ddb-java-migrate"></a>


****  

|  | 
| --- |
| 클라이언트 측 암호화 라이브러리의 이름이 AWS Database Encryption SDK로 변경되었습니다. 이 개발자 안내서는 여전히 [DynamoDB Encryption Client](legacy-dynamodb-encryption-client.md)에 대한 정보를 제공합니다. | 

DynamoDB용 Java 클라이언트측 암호화 라이브러리 버전 3.*x*는 2.*x* 코드 베이스를 대대적으로 재작성한 것입니다. 여기에는 새로운 구조화된 데이터 형식, 향상된 멀티테넌시 지원, 원활한 스키마 변경, 검색 가능한 암호화 지원 등 많은 업데이트가 포함되어 있습니다. 이 항목에서는 코드를 버전 3.*x*으로 마이그레이션하는 방법에 대한 지침을 제공합니다.

## 버전 1.x에서 2.x로 마이그레이션
<a name="ddb-java-v1-to-v2"></a>

버전 3.*x*로 마이그레이션하기 전에 버전 2.*x*로 마이그레이션합니다. 버전 2.*x*에서는 Most Recent Provider의 기호가 `MostRecentProvider`에서 `CachingMostRecentProvider`로 변경되었습니다. 현재 `MostRecentProvider` 기호와 함께 DynamoDB용 Java 클라이언트측 암호화 라이브러리 버전 1.*x* 를 사용하는 경우 코드의 기호 이름을 `CachingMostRecentProvider`으로 업데이트해야 합니다. 자세한 내용은 [Most Recent Provider 업데이트](most-recent-provider.md#mrp-versions)를 참조하세요.

## 버전 2.x에서 3.x로 마이그레이션
<a name="ddb-java-v2-to-v3"></a>

다음 절차에서는 코드를 DynamoDB용 Java 클라이언트측 암호화 라이브러리 버전 2.*x*에서 버전 3.*x*로 마이그레이션하는 방법을 설명합니다.

### 1단계. 새 형식의 항목을 읽을 준비하기
<a name="ddb-java-migrate-step1"></a>

다음 단계를 완료하여 AWS Database Encryption SDK 클라이언트가 새 형식으로 항목을 읽을 수 있도록 준비합니다. 다음 변경 사항을 배포한 후에도 클라이언트는 버전 2.*x*에서와 동일한 방식으로 계속 동작합니다. 클라이언트는 계속해서 버전 2.*x* 형식의 항목을 읽고 쓰지만 이러한 변경 사항을 통해 클라이언트는 [새 형식의 항목을 읽을 수 있도록](#ddb-java-migrate-step2) 준비합니다.

**를 버전 2.x AWS SDK for Java 로 업데이트**  
DynamoDB용 Java 클라이언트측 암호화 라이브러리 버전 3.*x*에는 [DynamoDB Enhanced Client](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/dynamodb-enhanced-client.html)가 필요합니다. DynamoDB Enhanced Client는 이전 버전에서 사용된 [DynamoDBMapper](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBMapper.Methods.html)를 대체합니다. 향상된 클라이언트를 사용하려면 AWS SDK for Java 2.x를 사용해야 합니다.  
[AWS SDK for Java의 버전 1.x에서 2.x로 마이그레이션하기](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/migration.html) 지침을 따르세요.  
필요한 AWS SDK for Java 2.x 모듈에 대한 자세한 내용은 섹션을 참조하세요[사전 조건](ddb-java.md#ddb-java-prerequisites).

**레거시 버전으로 암호화된 항목을 읽도록 클라이언트 구성**  
다음 절차는 아래 코드 예제에 나와 있는 단계의 개요를 제공합니다.  

1. [키링](keyrings.md)을 생성합니다.

   키링 및 [암호화 자료 관리자](concepts.md#crypt-materials-manager)는 이전 버전의 DynamoDB용 Java 클라이언트측 암호화 라이브러리에서 사용하던 암호화 자료 공급자를 대체합니다.
**중요**  
키링을 생성할 때 지정하는 래핑 키는 버전 2.*x*에서 암호화 자료 공급자에 사용한 래핑 키와 동일해야 합니다.

1. 주석이 달린 클래스 위에 테이블 스키마를 만듭니다.

   이 단계에서는 새 형식으로 항목을 작성하기 시작할 때 사용할 속성 작업을 정의합니다.

   새로운 DynamoDB Enhanced Client 사용에 대한 지침은 *AWS SDK for Java 개발자 안내서*의 [`TableSchema` 생성](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/ddb-en-client-gs-tableschema.html)을 참조하세요.

   다음 예제에서는 새 속성 작업 주석을 사용하여 버전 2.*x*에서 주석이 달린 클래스를 업데이트했다고 가정합니다. 속성 작업에 주석을 다는 방법에 대한 자세한 지침은 [주석이 달린 데이터 클래스 사용](ddb-java-using.md#ddb-attribute-actions-annotated-data-class)을 참조하세요.
**참고**  
`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 속성을 지정하는 경우 파티션 및 정렬 속성도 여야 합니다`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`. 를 정의하는 데 사용되는 주석을 보여주는 예제는 [SimpleClass4.java](https://github.com/aws/aws-database-encryption-sdk-dynamodb//blob/main/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/enhanced/SimpleClass4.java)를 `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`참조하세요.

1. [서명에서 제외할 속성](ddb-java-using.md#allowed-unauth)을 정의합니다.

1. 버전 2.x 모델 클래스에 구성된 속성 작업의 명시적 맵을 구성합니다.

   이 단계에서는 이전 형식으로 항목을 작성하는 데 사용되는 속성 작업을 정의합니다.

1. DynamoDB용 Java 클라이언트측 암호화 라이브러리 버전 2.*x*에서 사용한 `DynamoDBEncryptor`을 구성합니다.

1. 레거시 동작을 구성합니다.

1. `DynamoDbEncryptionInterceptor`를 만듭니다.

1. 새 AWS SDK DynamoDB 클라이언트를 생성합니다.

1. `DynamoDBEnhancedClient`를 만들고 모델링된 클래스로 테이블을 생성합니다.

   DynamoDB Enhanced Client에 대한 자세한 내용은 [향상된 클라이언트 생성](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/ddb-en-client-getting-started-dynamodbTable.html#ddb-en-client-getting-started-dynamodbTable-eclient)을 참조하세요.

```
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단계. 새 형식으로 항목 작성
<a name="ddb-java-migrate-step2"></a>

1단계의 변경 사항을 모든 리더에 배포한 후 다음 단계를 완료하여 새 형식으로 항목을 작성하도록 AWS Database Encryption SDK 클라이언트를 구성합니다. 다음 변경 사항을 배포한 후 클라이언트는 이전 형식의 항목을 계속 읽고 새 형식의 항목을 쓰고 읽기 시작합니다.

다음 절차는 아래 코드 예제에 나와 있는 단계의 개요를 제공합니다.

1. [**1단계**](#ddb-java-migrate-step1)에서 했던 것처럼 키링, 테이블 스키마, 레거시 속성 작업, `allowedUnsignedAttributes` 및 `DynamoDBEncryptor`를 계속 구성합니다.

1. 새 형식을 사용하여 새 항목만 작성하도록 레거시 동작을 업데이트합니다.

1. `DynamoDbEncryptionInterceptor ` 생성

1. 새 AWS SDK DynamoDB 클라이언트를 생성합니다.

1. `DynamoDBEnhancedClient`를 만들고 모델링된 클래스로 테이블을 생성합니다.

   DynamoDB Enhanced Client에 대한 자세한 내용은 [향상된 클라이언트 생성](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/ddb-en-client-getting-started-dynamodbTable.html#ddb-en-client-getting-started-dynamodbTable-eclient)을 참조하세요.

```
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단계](#ddb-java-migrate-step3)로 넘어갈 수 있습니다. 기존 항목을 빠르게 암호화하기 위해 실행할 수 있는 단일 지표나 쿼리는 없습니다. 시스템에 가장 적합한 프로세스를 사용하세요. 예를 들어, 테이블을 천천히 스캔한 다음 정의한 새 속성 작업 및 암호화 구성을 사용하여 항목을 다시 쓰는 비동기 프로세스를 사용할 수 있습니다.

### 3단계. 새 형식의 항목만 읽고 쓸 수 있습니다
<a name="ddb-java-migrate-step3"></a>

테이블의 모든 항목을 새 형식으로 다시 암호화한 후 구성에서 기존 동작을 제거할 수 있습니다. 클라이언트가 새 형식의 항목만 읽고 쓰도록 구성하려면 다음 단계를 수행합니다.

다음 절차는 아래 코드 예제에 나와 있는 단계의 개요를 제공합니다.

1. [**1단계에서**](#ddb-java-migrate-step1) 수행한 것처럼 키링, 테이블 스키마, `allowedUnsignedAttributes`을 계속 구성합니다. 구성에서 레거시 속성 작업 및 `DynamoDBEncryptor`을 제거합니다.

1. `DynamoDbEncryptionInterceptor`를 만듭니다.

1. 새 AWS SDK DynamoDB 클라이언트를 생성합니다.

1. `DynamoDBEnhancedClient`를 만들고 모델링된 클래스로 테이블을 생성합니다.

   DynamoDB Enhanced Client에 대한 자세한 내용은 [향상된 클라이언트 생성](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/ddb-en-client-getting-started-dynamodbTable.html#ddb-en-client-getting-started-dynamodbTable-eclient)을 참조하세요.

```
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);
    }
}
```