

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 設定現有的 DynamoDB 資料表以使用適用於 DynamoDB 的 AWS 資料庫加密 SDK
<a name="ddb-java-config-existing-table"></a>


****  

|  | 
| --- |
| 我們的用戶端加密程式庫已重新命名為 AWS 資料庫加密 SDK。此開發人員指南仍提供有關 [DynamoDB 加密用戶端](legacy-dynamodb-encryption-client.md)的資訊。 | 

使用適用於 DynamoDB 的 Java 用戶端加密程式庫 3.*x* 版，您可以將現有的 Amazon DynamoDB 資料表設定為用戶端加密。本主題提供將 3.*x* 版新增至現有填入的 DynamoDB 資料表之三個步驟的指引。

**先決條件**  
適用於 DynamoDB 的 Java 用戶端加密程式庫版本 3.*x* 需要 提供的 [DynamoDB 增強型用戶端](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/dynamodb-enhanced-client.html) AWS SDK for Java 2.x 。如果您仍然使用 [DynamoDBMapper](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBMapper.Methods.html)，您必須遷移至 AWS SDK for Java 2.x ，才能使用 DynamoDB 增強型用戶端。

 遵循[從 1.x 版遷移至 2.x 版 適用於 Java 的 AWS SDK](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/migration.html)的指示。

然後，遵循[使用 DynamoDB 增強型用戶端 API 開始使用](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/ddb-en-client-getting-started.html)的指示。

將資料表設定為使用 DynamoDB 的 Java 用戶端加密程式庫之前，您需要`TableSchema`[使用註釋的資料類別產生 ，](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/ddb-en-client-gs-tableschema.html#ddb-en-client-gs-tableschema-anno-bean)並[建立增強型用戶端](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)。

## 步驟 1：準備讀取和寫入加密的項目
<a name="ddb-java-add-step1"></a>

請完成下列步驟，以準備您的 AWS Database Encryption SDK 用戶端讀取和寫入加密的項目。部署下列變更後，用戶端將繼續讀取和寫入純文字項目。它不會加密或簽署寫入資料表的任何新項目，但一旦加密項目出現，它就能夠立即解密。這些變更可讓用戶端開始[加密新項目](#ddb-java-add-step2)。您必須先將下列變更部署到每個讀取器，才能繼續下一個步驟。

**1. 定義[您的屬性動作](concepts.md#crypt-actions)**  
更新您的註釋資料類別，以包含屬性動作，這些動作會定義哪些屬性值將加密和簽署、哪些屬性值只會簽署，以及哪些屬性值會被忽略。  
如需 DynamoDB 增強型用戶端註釋的詳細資訊，請參閱 GitHub 上 aws-database-encryption-sdk-dynamodb 儲存庫中的 [SimpleClass.java](https://github.com/aws/aws-database-encryption-sdk-dynamodb//blob/main/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/enhanced/SimpleClass.java)。 DynamoDB   
根據預設，主要金鑰屬性會經過簽署但未加密 (`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](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)。
如需註釋範例，請參閱 [使用標註的資料類別](ddb-java-using.md#ddb-attribute-actions-annotated-data-class)。

**2. 定義將從簽章中排除哪些屬性**  
下列範例假設所有`DO_NOTHING`屬性共用不同的字首「`:`」，並使用字首定義允許的未簽章屬性。用戶端將假設具有「`:`」字首的任何屬性名稱已從簽章中排除。如需詳細資訊，請參閱[Allowed unsigned attributes](ddb-java-using.md#allowed-unauth)。  

```
final String unsignedAttrPrefix = ":";
```

**3. 建立 [keyring](keyrings.md)**  
下列範例會建立 [AWS KMS keyring](use-kms-keyring.md)。 AWS KMS keyring 使用對稱加密或非對稱 RSA AWS KMS keys 來產生、加密和解密資料金鑰。  
此範例使用 `CreateMrkMultiKeyring`建立具有對稱加密 KMS 金鑰的 AWS KMS keyring。`CreateAwsKmsMrkMultiKeyring` 方法可確保 keyring 可正確處理單一區域和多區域金鑰。  

```
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 資料表加密組態 **  
下列範例會定義代表此 DynamoDB 資料表加密組態的`tableConfigs`映射。  
此範例指定 DynamoDB 資料表名稱做為[邏輯資料表名稱](ddb-java-using.md#logical-table-name)。當您第一次定義加密組態時，強烈建議指定您的 DynamoDB 資料表名稱做為邏輯資料表名稱。如需詳細資訊，請參閱[DynamoDB AWS 資料庫加密 SDK 中的加密組態](ddb-java-using.md#ddb-config-encrypt)。  
您必須指定 `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`**  
下列範例`DynamoDbEncryptionInterceptor`使用步驟 3 `tableConfigs`中的 建立 。 ****  

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

## 步驟 2：寫入加密和簽章的項目
<a name="ddb-java-add-step2"></a>

在您的`DynamoDbEncryptionInterceptor`組態中更新純文字政策，以允許用戶端寫入加密和簽署的項目。部署下列變更之後，用戶端會根據您在**步驟 1 **中設定的屬性動作來加密和簽署新項目。用戶端將能夠讀取純文字項目，以及加密和簽署的項目。

繼續進行[步驟 3](#ddb-java-add-step3) 之前，您必須加密並簽署資料表中的所有現有純文字項目。您可以執行沒有單一指標或查詢來快速加密現有的純文字項目。使用對您的系統最有意義的程序。例如，您可以使用慢速掃描資料表的非同步程序，並使用您定義的屬性動作和加密組態重寫項目。若要識別資料表中的純文字項目，建議您掃描所有不包含 AWS Database Encryption SDK 在加密`aws_dbe_head`和簽署項目時新增至項目的 和 `aws_dbe_foot` 屬性的項目。

下列範例會從**步驟 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：僅讀取加密和已簽章的項目
<a name="ddb-java-add-step3"></a>

在您加密並簽署所有項目之後，請更新`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);
```