

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

# Java 範例
<a name="ddb-java-examples"></a>


****  

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

下列範例示範如何使用適用於 DynamoDB 的 Java 用戶端加密程式庫來保護應用程式中的資料表項目。您可以在 GitHub 的 aws-database-encryption-sdk-dynamodb 儲存庫的 [Java 範例中](https://github.com/aws/aws-database-encryption-sdk-dynamodb//tree/main/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples)找到更多範例 （並自行提供）。

下列範例示範如何在未填入的新 Amazon DynamoDB 資料表中設定 DynamoDB 的 Java 用戶端加密程式庫。如果您想要設定現有的 Amazon DynamoDB 資料表進行用戶端加密，請參閱 [將 3.x 版新增至現有資料表](ddb-java-config-existing-table.md)。

**Topics**
+ [使用 DynamoDB 增強型用戶端](#ddb-java-enhanced-client-example)
+ [使用低階 DynamoDB API](#ddb-java-lowlevel-API-example)
+ [使用較低層級的 DynamoDbItemEncryptor](#ddb-java-itemencryptor)

## 使用 DynamoDB 增強型用戶端
<a name="ddb-java-enhanced-client-example"></a>

下列範例示範如何使用 DynamoDB 增強型用戶端和 `DynamoDbEncryptionInterceptor`搭配 [AWS KMS keyring](use-kms-keyring.md) 來加密 DynamoDB 資料表項目，做為 DynamoDB API 呼叫的一部分。

您可以搭配 DynamoDB 增強型用戶端使用任何支援的 [keyring](keyrings.md)，但我們建議您盡可能使用其中一個 AWS KMS keyring。

**注意**  
DynamoDB 增強型用戶端不支援[可搜尋加密](searchable-encryption.md)。使用 `DynamoDbEncryptionInterceptor`搭配低階 DynamoDB API，以使用可搜尋的加密。

**請參閱完整的程式碼範例**：[EnhancedPutGetExample.java](https://github.com/aws/aws-database-encryption-sdk-dynamodb//blob/main/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/enhanced/EnhancedPutGetExample.java)

**步驟 1：建立 AWS KMS keyring**  
下列範例使用 `CreateAwsKmsMrkMultiKeyring`建立具有對稱加密 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);
```

**步驟 2：從註釋的資料類別建立資料表結構描述**  
下列範例使用註釋的資料類別來建立 `TableSchema`。  
此範例假設已使用 [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) 定義註釋的資料類別和屬性動作。如需註釋屬性動作的更多指引，請參閱 [使用標註的資料類別](ddb-java-using.md#ddb-attribute-actions-annotated-data-class)。  
 AWS Database Encryption SDK 不支援[巢狀屬性](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/ddb-en-client-adv-features-nested.html)上的註釋。

```
final TableSchema<SimpleClass> schemaOnEncrypt = TableSchema.fromBean(SimpleClass.class);
```

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

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

**步驟 4：建立加密組態**  
下列範例定義代表 DynamoDB 資料表加密組態的`tableConfigs`映射。  
此範例指定 DynamoDB 資料表名稱做為[邏輯資料表名稱](ddb-java-using.md#logical-table-name)。當您第一次定義加密組態時，強烈建議指定您的 DynamoDB 資料表名稱做為邏輯資料表名稱。如需詳細資訊，請參閱[DynamoDB AWS 資料庫加密 SDK 中的加密組態](ddb-java-using.md#ddb-config-encrypt)。  
若要使用[可搜尋加密](searchable-encryption.md)或[已簽章的信標](configure.md#signed-beacons)，您還必須在加密組態[`SearchConfig`](ddb-java-using.md#ddb-search-config)中包含 。

```
final Map<String, DynamoDbEnhancedTableEncryptionConfig> tableConfigs = new HashMap<>();
tableConfigs.put(ddbTableName,
    DynamoDbEnhancedTableEncryptionConfig.builder()
        .logicalTableName(ddbTableName)
        .keyring(kmsKeyring)
        .allowedUnsignedAttributePrefix(unsignedAttrPrefix)
        .schemaOnEncrypt(tableSchema)
        .build());
```

**步驟 5：建立 `DynamoDbEncryptionInterceptor`**  
下列範例會使用**步驟 4 **`DynamoDbEncryptionInterceptor``tableConfigs`中的 建立新的 。  

```
final DynamoDbEncryptionInterceptor interceptor =
    DynamoDbEnhancedClientEncryption.CreateDynamoDbEncryptionInterceptor(
        CreateDynamoDbEncryptionInterceptorInput.builder()
            .tableEncryptionConfigs(tableConfigs)
            .build()
    );
```

**步驟 6：建立新的 AWS SDK DynamoDB 用戶端**  
下列範例使用步驟 5 `interceptor`中的 建立新的 AWS SDK DynamoDB 用戶端。 ****  

```
final DynamoDbClient ddb = DynamoDbClient.builder()
        .overrideConfiguration(
                ClientOverrideConfiguration.builder()
                       .addExecutionInterceptor(interceptor)
                       .build())
        .build();
```

**步驟 7：建立 DynamoDB 增強型用戶端並建立資料表**  
下列範例使用**步驟 6** 中建立的 AWS SDK DynamoDB 用戶端建立 DynamoDB 增強型用戶端，並使用註釋的資料類別建立資料表。  

```
final DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder()
        .dynamoDbClient(ddb)
        .build();
final DynamoDbTable<SimpleClass> table = enhancedClient.table(ddbTableName, tableSchema);
```

**步驟 8：加密和簽署資料表項目**  
下列範例會使用 DynamoDB 增強型用戶端將項目放入 DynamoDB 資料表。項目在傳送至 DynamoDB 之前，會先加密並簽署用戶端。  

```
final SimpleClass item = new SimpleClass();
item.setPartitionKey("EnhancedPutGetExample");
item.setSortKey(0);
item.setAttribute1("encrypt and sign me!");
item.setAttribute2("sign me!");
item.setAttribute3("ignore me!");

table.putItem(item);
```

## 使用低階 DynamoDB API
<a name="ddb-java-lowlevel-API-example"></a>

下列範例示範如何使用低階 DynamoDB API 搭配 [AWS KMS keyring](use-kms-keyring.md)，以自動加密和簽署具有 DynamoDB `PutItem`請求的用戶端項目。

您可以使用任何支援的 [keyring](keyrings.md)，但我們建議您盡可能使用其中一個 AWS KMS keyring。

**請參閱完整的程式碼範例**：[BasicPutGetExample.java](https://github.com/aws/aws-database-encryption-sdk-dynamodb//blob/main/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/BasicPutGetExample.java)

**步驟 1：建立 AWS KMS keyring**  
下列範例使用 `CreateAwsKmsMrkMultiKeyring`建立具有對稱加密 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);
```

**步驟 2：設定屬性動作**  
下列範例定義代表資料表項目範例[屬性動作](concepts.md#crypt-actions)的`attributeActionsOnEncrypt`映射。  
下列範例不會將任何屬性定義為 `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`。如果您指定任何`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`屬性，則分割區和排序屬性也必須是 `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`。

```
final Map<String, CryptoAction> attributeActionsOnEncrypt = new HashMap<>();
// The partition attribute must be SIGN_ONLY
attributeActionsOnEncrypt.put("partition_key", CryptoAction.SIGN_ONLY); 
// The sort attribute must be SIGN_ONLY
attributeActionsOnEncrypt.put("sort_key", CryptoAction.SIGN_ONLY); 
attributeActionsOnEncrypt.put("attribute1", CryptoAction.ENCRYPT_AND_SIGN);
attributeActionsOnEncrypt.put("attribute2", CryptoAction.SIGN_ONLY);
attributeActionsOnEncrypt.put(":attribute3", CryptoAction.DO_NOTHING);
```

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

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

**步驟 4：定義 DynamoDB 資料表加密組態**  
下列範例會定義代表此 DynamoDB 資料表加密組態的`tableConfigs`映射。  
此範例會將 DynamoDB 資料表名稱指定為[邏輯資料表名稱](ddb-java-using.md#logical-table-name)。當您第一次定義加密組態時，強烈建議指定您的 DynamoDB 資料表名稱做為邏輯資料表名稱。如需詳細資訊，請參閱[DynamoDB AWS 資料庫加密 SDK 中的加密組態](ddb-java-using.md#ddb-config-encrypt)。  
若要使用[可搜尋加密](searchable-encryption.md)或[已簽章的信標](configure.md#signed-beacons)，您還必須在加密組態[`SearchConfig`](ddb-java-using.md#ddb-search-config)中包含 。

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

**步驟 5：建立 `DynamoDbEncryptionInterceptor`**  
下列範例`DynamoDbEncryptionInterceptor`使用步驟 4 `tableConfigs`中的 建立 。 ****  

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

**步驟 6：建立新的 AWS SDK DynamoDB 用戶端**  
下列範例使用步驟 5 `interceptor`中的 建立新的 AWS SDK DynamoDB 用戶端。 ****  

```
final DynamoDbClient ddb = DynamoDbClient.builder()
        .overrideConfiguration(
                ClientOverrideConfiguration.builder()
                       .addExecutionInterceptor(interceptor)
                       .build())
        .build();
```

**步驟 7：加密並簽署 DynamoDB 資料表項目**  
下列範例定義代表範例資料表項目的`item`映射，並將該項目放在 DynamoDB 資料表中。項目會在傳送至 DynamoDB 之前加密並簽署用戶端。  

```
final HashMap<String, AttributeValue> item = new HashMap<>();
item.put("partition_key", AttributeValue.builder().s("BasicPutGetExample").build());
item.put("sort_key", AttributeValue.builder().n("0").build());
item.put("attribute1", AttributeValue.builder().s("encrypt and sign me!").build());
item.put("attribute2", AttributeValue.builder().s("sign me!").build());
item.put(":attribute3", AttributeValue.builder().s("ignore me!").build());

final PutItemRequest putRequest = PutItemRequest.builder()
        .tableName(ddbTableName)
        .item(item)
        .build();

final PutItemResponse putResponse = ddb.putItem(putRequest);
```

## 使用較低層級的 DynamoDbItemEncryptor
<a name="ddb-java-itemencryptor"></a>

下列範例示範如何使用較低層級`DynamoDbItemEncryptor`的 [AWS KMS keyring](use-kms-keyring.md) 來直接加密和簽署資料表項目。`DynamoDbItemEncryptor` 不會將項目放在 DynamoDB 資料表中。

您可以搭配 DynamoDB 增強型用戶端使用任何支援的 [keyring](keyrings.md)，但我們建議您盡可能使用其中一個 AWS KMS keyring。

**注意**  
較低層級`DynamoDbItemEncryptor`不支援[可搜尋的加密](searchable-encryption.md)。使用 `DynamoDbEncryptionInterceptor`搭配低階 DynamoDB API，以使用可搜尋的加密。

**請參閱完整的程式碼範例**：I [ItemEncryptDecryptExample.java](https://github.com/aws/aws-database-encryption-sdk-dynamodb//blob/main/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/itemencryptor/ItemEncryptDecryptExample.java)

**步驟 1：建立 AWS KMS keyring**  
下列範例使用 `CreateAwsKmsMrkMultiKeyring`建立具有對稱加密 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);
```

**步驟 2：設定屬性動作**  
下列範例定義代表資料表項目範例[屬性動作](concepts.md#crypt-actions)的`attributeActionsOnEncrypt`映射。  
下列範例不會將任何屬性定義為 `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`。如果您指定任何`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`屬性，則分割區和排序屬性也必須是 `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`。

```
final Map<String, CryptoAction> attributeActionsOnEncrypt = new HashMap<>();
// The partition attribute must be SIGN_ONLY
attributeActionsOnEncrypt.put("partition_key", CryptoAction.SIGN_ONLY); 
// The sort attribute must be SIGN_ONLY
attributeActionsOnEncrypt.put("sort_key", CryptoAction.SIGN_ONLY); 
attributeActionsOnEncrypt.put("attribute1", CryptoAction.ENCRYPT_AND_SIGN);
attributeActionsOnEncrypt.put("attribute2", CryptoAction.SIGN_ONLY);
attributeActionsOnEncrypt.put(":attribute3", CryptoAction.DO_NOTHING);
```

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

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

**步驟 4：定義`DynamoDbItemEncryptor`組態**  
下列範例定義 的組態`DynamoDbItemEncryptor`。  
此範例會將 DynamoDB 資料表名稱指定為[邏輯資料表名稱](ddb-java-using.md#logical-table-name)。當您第一次定義加密組態時，強烈建議指定您的 DynamoDB 資料表名稱做為邏輯資料表名稱。如需詳細資訊，請參閱[DynamoDB AWS 資料庫加密 SDK 中的加密組態](ddb-java-using.md#ddb-config-encrypt)。  

```
final DynamoDbItemEncryptorConfig config = DynamoDbItemEncryptorConfig.builder()
        .logicalTableName(ddbTableName)
        .partitionKeyName("partition_key")
        .sortKeyName("sort_key")
        .attributeActionsOnEncrypt(attributeActionsOnEncrypt)
        .keyring(kmsKeyring)
        .allowedUnsignedAttributePrefix(unsignedAttrPrefix)
        .build();
```

**步驟 5：建立 `DynamoDbItemEncryptor`**  
下列範例`DynamoDbItemEncryptor`使用**步驟 4 **`config`中的 建立新的 。  

```
final DynamoDbItemEncryptor itemEncryptor = DynamoDbItemEncryptor.builder()
        .DynamoDbItemEncryptorConfig(config)
        .build();
```

**步驟 6：直接加密和簽署資料表項目**  
下列範例使用 直接加密和簽署項目`DynamoDbItemEncryptor`。`DynamoDbItemEncryptor` 不會將項目放在 DynamoDB 資料表中。  

```
final Map<String, AttributeValue> originalItem = new HashMap<>();
originalItem.put("partition_key", AttributeValue.builder().s("ItemEncryptDecryptExample").build());
originalItem.put("sort_key", AttributeValue.builder().n("0").build());
originalItem.put("attribute1", AttributeValue.builder().s("encrypt and sign me!").build());
originalItem.put("attribute2", AttributeValue.builder().s("sign me!").build());
originalItem.put(":attribute3", AttributeValue.builder().s("ignore me!").build());

final Map<String, AttributeValue> encryptedItem = itemEncryptor.EncryptItem(
        EncryptItemInput.builder()
                .plaintextItem(originalItem)
                .build()
).encryptedItem();
```