

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# DynamoDB 用の Java クライアント側の暗号化ライブラリの使用
<a name="ddb-java-using"></a>


****  

|  | 
| --- |
| クライアント側の暗号化ライブラリの名前が AWS Database Encryption SDK に変更されました。このデベロッパーガイドでは、引き続き [DynamoDB Encryption Client](legacy-dynamodb-encryption-client.md) に関する情報を提供します。 | 

このトピックでは、DynamoDB 用の Java クライアント側の暗号化ライブラリのバージョン 3.x の関数とヘルパークラスの一部について説明します。

DynamoDB 用の Java クライアント側の暗号化ライブラリを使用したプログラミングの詳細については、GitHub の aws-database-encryption-sdk-dynamodb リポジトリにある [Java の例](java-examples.md)、[Java の例](https://github.com/aws/aws-database-encryption-sdk-dynamodb//tree/main/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples)を参照してください。

**Topics**
+ [項目エンクリプタ](#ddb-item-encryptors)
+ [属性アクション](#ddb-attribute-actions)
+ [暗号化設定](#ddb-config-encrypt)
+ [項目の更新](#ddb-update-items)
+ [署名付きセットの復号化](#ddb-java-signed-sets)

## 項目エンクリプタ
<a name="ddb-item-encryptors"></a>

その中核となる AWS Database Encryption SDK for DynamoDB は項目エンクリプタです。DynamoDB 用の Java クライアント側の暗号化ライブラリのバージョン 3.x を使用して、次の方法で DynamoDB テーブル項目の暗号化、署名、検証、および復号を行うことができます。

**DynamoDB Enhanced Client**  
DynamoDB `PutItem` リクエストを使用してクライアント側で項目を自動的に暗号化して署名するように、`DynamoDbEncryptionInterceptor` で [DynamoDB Enhanced Client](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/dynamodb-enhanced-client.html) を設定できます。DynamoDB Enhanced Client を使用すると、[アノテーション付きデータクラス](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/ddb-en-client-gs-tableschema.html#ddb-en-client-gs-tableschema-anno-bean)を使用して属性アクションを定義できます。可能な場合は常に、DynamoDB Enhanced Client を使用することをお勧めします。  
DynamoDB Enhanced Client は、[検索可能な暗号化](searchable-encryption.md)をサポートしていません。  
 AWS Database Encryption SDK は、[ネストされた属性](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/ddb-en-client-adv-features-nested.html)の注釈をサポートしていません。

**下位レベルの DynamoDB API**  
DynamoDB `PutItem` リクエストを使用してクライアント側で項目を自動的に暗号化して署名するように、`DynamoDbEncryptionInterceptor` で[下位レベルの DynamoDB API](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Programming.LowLevelAPI.html) を設定できます。  
[検索可能な暗号化](searchable-encryption.md)を使用するには、下位レベルの DynamoDB API を使用する必要があります。

**下位レベルの `DynamoDbItemEncryptor`**  
下位レベルの `DynamoDbItemEncryptor` は、DynamoDB を呼び出すことなく、テーブル項目を直接暗号化して署名するか、または復号して検証します。DynamoDB の `PutItem` または `GetItem` リクエストは実行しません。例えば、下位レベルの `DynamoDbItemEncryptor` を使用して、既に取得した DynamoDB 項目を直接復号して検証できます。  
下位レベルの `DynamoDbItemEncryptor` は、[検索可能な暗号化](searchable-encryption.md)をサポートしていません。

## AWS Database Encryption SDK for DynamoDB の属性アクション
<a name="ddb-attribute-actions"></a>

[属性アクション](concepts.md#crypt-actions)は、暗号化および署名される属性値を決定します。この属性値は署名のみされ、署名されて暗号化コンテキストに含まれ、無視されます。

**注記**  
`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 暗号化アクションを使用するには、 AWS Database Encryption SDK のバージョン 3.3 以降を使用する必要があります。[データモデルを更新して を含める前に、すべてのリーダー](ddb-update-data-model.md)に新しいバージョンをデプロイします`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`。

下位レベルの DynamoDB API または下位レベルの `DynamoDbItemEncryptor` を使用する場合は、属性アクションを手動で定義する必要があります。DynamoDB Enhanced Client を使用する場合は、属性アクションを手動で定義するか、またはアノテーション付きデータクラスを使用して、[`TableSchema` を生成](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/ddb-en-client-gs-tableschema.html)できます。設定プロセスを簡素化するには、アノテーション付きデータクラスを使用することをお勧めします。アノテーション付きデータクラスを使用する場合、オブジェクトを 1 回だけモデル化する必要があります。

**注記**  
属性アクションを定義した後、どの属性を署名から除外するかを定義する必要があります。将来、新しい署名なし属性を簡単に追加できるように、署名なし属性を識別するための個別のプレフィックス (「`:`」など) を選択することをお勧めします。DynamoDB スキーマと属性アクションを定義するときに `DO_NOTHING` とマークされたすべての属性の属性名にこのプレフィックスを含めます。

### アノテーション付きデータクラスを使用する
<a name="ddb-attribute-actions-annotated-data-class"></a>

[アノテーション付きデータクラス](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/ddb-en-client-gs-tableschema.html#ddb-en-client-gs-tableschema-anno-bean)を使用して、DynamoDB Enhanced Client および `DynamoDbEncryptionInterceptor` で属性アクションを指定します。 AWS Database Encryption SDK for DynamoDB は、[標準の DynamoDB 属性の注釈](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/mapper/annotations/package-summary.html)を使用して、属性を保護する方法を決定する属性のタイプを定義します。デフォルトでは、プライマリキーを除く属性がすべて暗号化されます。これらの属性は署名されますが、暗号化はされません。

**注記**  
`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 暗号化アクションを使用するには、 AWS Database Encryption SDK のバージョン 3.3 以降を使用する必要があります。[データモデルを更新して を含める前に、すべてのリーダー](ddb-update-data-model.md)に新しいバージョンをデプロイします`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`。

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) を参照してください。

デフォルトでは、プライマリキー属性は署名されてはいるが、暗号化されておらず (`SIGN_ONLY`)、他のすべての属性は暗号化されて署名されています (`ENCRYPT_AND_SIGN`)。属性を として定義する場合`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`、パーティション属性とソート属性も である必要があります`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`。例外を指定するには、DynamoDB 用の Java クライアント側の暗号化ライブラリで定義されている暗号化アノテーションを使用します。例えば、特定の属性を署名のみにしたい場合は、`@DynamoDbEncryptionSignOnly` アノテーションを使用します。特定の属性に署名して暗号化コンテキストに含める場合は、 を使用します`@DynamoDbEncryptionSignAndIncludeInEncryptionContext`。特定の属性が署名も暗号化もされないようにしたい場合 (`DO_NOTHING`) は、`@DynamoDbEncryptionDoNothing` アノテーションを使用します。

**注記**  
 AWS Database Encryption SDK は、[ネストされた属性](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/ddb-en-client-adv-features-nested.html)の注釈をサポートしていません。

次の例は、`ENCRYPT_AND_SIGN`、、`SIGN_ONLY`および `DO_NOTHING`属性アクションの定義に使用される注釈を示しています。の定義に使用される注釈の例については`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)」を参照してください。

```
@DynamoDbBean
public class SimpleClass {

    private String partitionKey;
    private int sortKey;
    private String attribute1;
    private String attribute2;
    private String attribute3;

    @DynamoDbPartitionKey
    @DynamoDbAttribute(value = "partition_key")
    public String getPartitionKey() {
        return this.partitionKey;
    }

    public void setPartitionKey(String partitionKey) {
        this.partitionKey = partitionKey;
    }

    @DynamoDbSortKey
    @DynamoDbAttribute(value = "sort_key")
    public int getSortKey() {
        return this.sortKey;
    }

    public void setSortKey(int sortKey) {
        this.sortKey = sortKey;
    }

    public String getAttribute1() {
        return this.attribute1;
    }

    public void setAttribute1(String attribute1) {
        this.attribute1 = attribute1;
    }

    @DynamoDbEncryptionSignOnly
    public String getAttribute2() {
        return this.attribute2;
    }

    public void setAttribute2(String attribute2) {
        this.attribute2 = attribute2;
    }

    @DynamoDbEncryptionDoNothing
    public String getAttribute3() {
        return this.attribute3;
    }

    @DynamoDbAttribute(value = ":attribute3")
    public void setAttribute3(String attribute3) {
        this.attribute3 = attribute3;
    }
    
}
```

次のスニペットに示すように、アノテーション付きデータクラスを使用して `TableSchema` を作成します。

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

### 属性アクションを手動で定義する
<a name="ddb-attribute-actions-manual"></a>

属性アクションを手動で指定するには、名前と値のペアが属性名と指定されたアクションを表す `Map` オブジェクトを作成します。

属性を暗号化して署名するように `ENCRYPT_AND_SIGN` を指定します。属性に署名するが暗号化はしないように `SIGN_ONLY` を指定します。`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` を指定して属性に署名し、暗号化コンテキストに含めます。属性に署名することなく、その属性を暗号化することはできません。属性を無視するように `DO_NOTHING` を指定します。

パーティション属性とソート属性は、 `SIGN_ONLY` または のいずれかである必要があります`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`。属性を として定義する場合`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`、パーティション属性とソート属性も である必要があります`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`。

**注記**  
`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 暗号化アクションを使用するには、 AWS Database Encryption SDK のバージョン 3.3 以降を使用する必要があります。[データモデルを更新して を含める前に、すべてのリーダー](ddb-update-data-model.md)に新しいバージョンをデプロイします`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`。

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

## AWS Database Encryption SDK for DynamoDB の暗号化設定
<a name="ddb-config-encrypt"></a>

 AWS Database Encryption SDK を使用する場合は、DynamoDB テーブルの暗号化設定を明示的に定義する必要があります。暗号化設定に必要な値は、属性アクションを手動で定義したか、またはアノテーション付きデータクラスを使用して定義したかによって異なります。

次のスニペットは、DynamoDB Enhanced Client、[https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/ddb-en-client-gs-tableschema.html](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/ddb-en-client-gs-tableschema.html)、および個別のプレフィックスによって定義された、許可された署名なし属性を使用して、DynamoDB テーブルの暗号化設定を定義します。

```
final Map<String, DynamoDbEnhancedTableEncryptionConfig> tableConfigs = new HashMap<>();
tableConfigs.put(ddbTableName,
        DynamoDbEnhancedTableEncryptionConfig.builder()
            .logicalTableName(ddbTableName)
            .keyring(kmsKeyring)
            .allowedUnsignedAttributePrefix(unsignedAttrPrefix)
            .schemaOnEncrypt(tableSchema)
            // Optional: only required if you use beacons
            .search(SearchConfig.builder() 
                    .writeVersion(1) // MUST be 1
                    .versions(beaconVersions)
                    .build())         
            .build());
```

**論理テーブル名**  
DynamoDB テーブルの論理テーブル名。  
論理テーブル名は、DynamoDB の復元オペレーションを簡素化するために、テーブルに格納されているすべてのデータに暗号的にバインドされます。最初に暗号化設定を定義する際に、DynamoDB テーブル名を論理テーブル名として指定することを強くお勧めします。常に同じ論理テーブル名を指定する必要があります。復号を成功させるには、論理テーブル名が、暗号化の際に指定された名前と一致する必要があります。[DynamoDB テーブルをバックアップから復元](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Restore.Tutorial.html)した後に DynamoDB テーブル名が変更された場合でも、論理テーブル名を使用することで、復号オペレーションで引き続きテーブルが確実に認識されます。

**許可された署名なし属性**  
属性アクションで `DO_NOTHING` とマークされた属性。  
許可された署名なし属性は、どの属性が署名から除外されるかをクライアントに伝えます。クライアントは、他のすべての属性が署名に含まれていると想定します。その後、レコードを復号する際に、クライアントは、ユーザーが指定する、許可された署名なし属性の中からどの属性を検証する必要があり、どの属性を無視する必要があるかを決定します。許可された署名なし属性から属性を削除することはできません。  
すべての `DO_NOTHING` 属性をリストする配列を作成することで、許可された署名なし属性を明示的に定義できます。また、`DO_NOTHING` 属性に名前を付ける際に個別のプレフィックスを指定し、そのプレフィックスを使用してどの属性が署名されていないかをクライアントに伝えることもできます。将来新しい `DO_NOTHING` 属性を追加するプロセスが簡素化されるため、個別のプレフィックスを指定することを強くお勧めします。詳細については、「[データモデルの更新](ddb-update-data-model.md)」を参照してください。  
すべての `DO_NOTHING` 属性のためにプレフィックスを指定しない場合は、クライアントが復号時に署名されていないことを想定するすべての属性を明示的にリストする `allowedUnsignedAttributes` 配列を設定できます。どうしても必要な場合にのみ、許可された署名なし属性を明示的に定義する必要があります。

**検索設定 (オプション)**  
`SearchConfig` は[ビーコンのバージョン](using-beacons.md#beacon-version)を定義します。  
[検索可能な暗号化](searchable-encryption.md)または[署名付きビーコン](configure.md#signed-beacons)を使用するには、`SearchConfig` を指定する必要があります。

**アルゴリズムスイート (オプション)**  
`algorithmSuiteId` は、 AWS Database Encryption SDK が使用するアルゴリズムスイートを定義します。  
代替アルゴリズムスイートを明示的に指定しない限り、 AWS Database Encryption SDK は[デフォルトのアルゴリズムスイート](supported-algorithms.md#recommended-algorithms)を使用します。デフォルトのアルゴリズムスイートは、キーの導出、[デジタル署名](concepts.md#digital-sigs)、および[キーコミットメント](concepts.md#key-commitment)を備えた AES-GCM アルゴリズムを使用します。デフォルトのアルゴリズムスイートはほとんどのアプリケーションに適している可能性がありますが、代替アルゴリズムスイートを選択できます。例えば、一部の信頼モデルは、デジタル署名を含まないアルゴリズムスイートによって満たされます。 AWS Database Encryption SDK がサポートするアルゴリズムスイートの詳細については、「」を参照してください[AWS Database Encryption SDK でサポートされているアルゴリズムスイート](supported-algorithms.md)。  
[ECDSA デジタル署名のない AES-GCM アルゴリズムスイート](supported-algorithms.md#other-algorithms)を選択するには、テーブル暗号化設定に次のスニペットを含めます。  

```
.algorithmSuiteId(
    DBEAlgorithmSuiteId.ALG_AES_256_GCM_HKDF_SHA512_COMMIT_KEY_SYMSIG_HMAC_SHA384)
```

## AWS Database Encryption SDK を使用した項目の更新
<a name="ddb-update-items"></a>

 AWS Database Encryption SDK は、暗号化または署名された項目に対して [ddb:UpdateItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateItem.html) をサポートしていません。暗号化または署名された項目を更新するには、[ddb:PutItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html) を使用する必要があります。`PutItem` リクエストで既存の項目と同じプライマリキーを指定すると、新しい項目が既存の項目に完全に置き換わります。[CLOBBER](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/datamodeling/DynamoDBMapperConfig.SaveBehavior.html#CLOBBER) を使用して、項目を更新した後、保存する際にすべての属性をクリアして置き換えることもできます。

## 署名付きセットの復号化
<a name="ddb-java-signed-sets"></a>

 AWS Database Encryption SDK のバージョン 3.0.0 および 3.1.0 では、[セットタイプ](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.NamingRulesDataTypes.html#HowItWorks.DataTypes.SetTypes)属性を として定義した場合`SIGN_ONLY`、セットの値は指定された順序で正規化されます。DynamoDB はセットの順序を保持しません。その結果、セットを含む項目の署名の検証が失敗する可能性があります。セットの値が AWS Database Encryption SDK に提供された順序とは異なる順序で返されると、セット属性に同じ値が含まれている場合でも、署名の検証は失敗します。

**注記**  
 AWS Database Encryption SDK のバージョン 3.1.1 以降では、すべてのセットタイプ属性の値が正規化されるため、DynamoDB に書き込まれたのと同じ順序で値が読み取られます。

署名の検証が失敗すると、復号オペレーションは失敗して以下のエラーメッセージを返します。


|  | 
| --- |
| software.amazon.cryptography.dbencryptionsdk.structuredencryption.model.StructuredEncryptionException: 受信者タグが一致しませんでした。 | 

上記のエラーメッセージが表示され、復号化しようとしているアイテムにバージョン 3.0.0 または 3.1.0 を使用して署名されたセットが含まれていると思われる場合、セットを正常に検証する方法の詳細として GitHub の aws-database-encryption-sdk-dynamodb-java リポジトリの [DecryptWithPermute](https://github.com/aws/aws-database-encryption-sdk-dynamodb-java/tree/v3.1.1/DecryptWithPermute) ディレクトリを参照してください。