

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

# Amazon DynamoDB Encryption Client for Java
<a name="java"></a>

**注記**  
クライアント側の暗号化ライブラリの名前が [AWS Database Encryption SDK](DDBEC-rename.md) に変更されました。次のトピックには、DynamoDB Encryption Client for Java のバージョン 1.x～2.x および DynamoDB Encryption Client for Python のバージョン 1.x～3.x に関する情報が記載されています。詳細については、「[AWS Database Encryption SDK for DynamoDB バージョンのサポート](legacy-dynamodb-encryption-client.md#legacy-support)」を参照してください。

このトピックでは、Amazon DynamoDB Encryption Client for Java をインストールして使用する方法について説明します。DynamoDB 暗号化クライアントを使用したプログラミングの詳細については、[Java の例](java-examples.md)、GitHub の aws-dynamodb-encryption-java リポジトリにある[例](https://github.com/aws/aws-dynamodb-encryption-java/tree/master/examples)、および DynamoDB 暗号化クライアント用の [Javadoc](https://aws.github.io/aws-dynamodb-encryption-java/) を参照してください。

**注記**  
DynamoDB Encryption Client for Java のバージョン 1.x.x は、2022 年 7 月に[サポート終了フェーズ](what-is-database-encryption-sdk.md#support)に入ります。可能な限り早急に新しいバージョンにアップグレードしてください。

**Topics**
+ [前提条件](#java-prerequisites)
+ [インストール](#java-installation)
+ [Java 用 Amazon DynamoDB 暗号化クライアントの使用方法](java-using.md)
+ [Java の例](java-examples.md)

## 前提条件
<a name="java-prerequisites"></a>

Amazon DynamoDB Encryption Client for Java をインストールする前に、以下の前提条件が満たされていることを確認してください。

**Java 開発環境**  
Java 8 以降が必要になります。Oracle のウェブサイトで [Java SE のダウンロード](https://www.oracle.com/java/technologies/downloads/)に移動し、Java SE Development Kit (JDK) をダウンロードして、インストールします。  
Oracle JDK を使用する場合は、[Java Cryptography Extension (JCE) 無制限強度の管轄ポリシーファイル](http://www.oracle.com/java/technologies/javase-jce8-downloads.html)をダウンロードして、インストールする必要があります。

**AWS SDK for Java**  
DynamoDB 暗号化クライアントには、アプリケーションが DynamoDB とやり取りしない場合 AWS SDK for Java でも、 の DynamoDB モジュールが必要です。SDK 全体またはこのモジュールだけをインストールできます。Maven を使用している場合は、`aws-java-sdk-dynamodb` を `pom.xml` ファイルに追加します。  
のインストールと設定の詳細については AWS SDK for Java、「」を参照してください[AWS SDK for Java](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/getting-started.html)。

## インストール
<a name="java-installation"></a>

Amazon DynamoDB Encryption Client for Java は、以下の方法でインストールできます。

**手動**  
Amazon DynamoDB Encryption Client for Java をインストールするには、[aws-dynamodb-encryption-java](https://github.com/aws/aws-dynamodb-encryption-java/) GitHub リポジトリをクローンまたはダウンロードしてください。

**Apache Maven の使用**  
Amazon DynamoDB Encryption Client for Java は、以下の依存定義を使用して、[Apache Maven](https://maven.apache.org/) を介して利用できます。  

```
<dependency>
  <groupId>com.amazonaws</groupId>
  <artifactId>aws-dynamodb-encryption-java</artifactId>
  <version>version-number</version>
</dependency>
```

SDK をインストールしたら、このガイドと GitHub の [DynamoDB 暗号化クライアント Javadoc](https://aws.github.io/aws-dynamodb-encryption-java/) のサンプルコードを確認して開始します。

# Java 用 Amazon DynamoDB 暗号化クライアントの使用方法
<a name="java-using"></a>

**注記**  
クライアント側の暗号化ライブラリの名前が [AWS Database Encryption SDK](DDBEC-rename.md) に変更されました。次のトピックには、DynamoDB Encryption Client for Java のバージョン 1.x～2.x および DynamoDB Encryption Client for Python のバージョン 1.x～3.x に関する情報が記載されています。詳細については、「[AWS Database Encryption SDK for DynamoDB バージョンのサポート](legacy-dynamodb-encryption-client.md#legacy-support)」を参照してください。

このトピックでは、Java での Amazon DynamoDB 暗号化クライアントの機能の一部について説明します。他のプログラミング言語には実装されていない機能も含まれます。

DynamoDB 暗号化クライアントを使用したプログラミングの詳細については、[Java の例](java-examples.md)、GitHub の `aws-dynamodb-encryption-java repository` にある[例](https://github.com/aws/aws-dynamodb-encryption-java/tree/master/examples)、および DynamoDB 暗号化クライアント用の [Javadoc](https://aws.github.io/aws-dynamodb-encryption-java/) を参照してください。



**Topics**
+ [項目エンクリプタ](#attribute-encryptor)
+ [保存動作の設定](#save-behavior)
+ [Java の属性アクション](#attribute-actions-java)
+ [テーブル名の上書き](#override-table-name)

## 項目エンクリプタ: AttributeEncryptor および DynamoDBEncryptor
<a name="attribute-encryptor"></a>

Java の DynamoDB 暗号化クライアントには、下位レベルの [DynamoDBEncryptor](https://aws.github.io/aws-dynamodb-encryption-java/com/amazonaws/services/dynamodbv2/datamodeling/encryption/DynamoDBEncryptor.html) および [AttributeEncryptor](#attribute-encryptor) という 2 つの[項目エンクリプタ](DDBEC-legacy-concepts.md#item-encryptor)があります。

`AttributeEncryptor` は、DynamoDB 暗号化クライアントの で [DynamoDBMapper](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBMapper.Methods.html) `DynamoDB Encryptor` を使用するのに役立つヘルパークラスです。 AWS SDK for Java DynamoDB `DynamoDBMapper` で `AttributeEncryptor` を使用すると、項目の保存時に項目が透過的に暗号化および署名されます。また、項目のロード時に項目が透過的に検証および復号されます。

## 保存動作の設定
<a name="save-behavior"></a>

`AttributeEncryptor` および `DynamoDBMapper` を使用して、署名のみが行われた属性または暗号化および署名された属性を持つテーブル項目を追加またはレプリケートできます。これらのタスクでは、次の例に示すように、`PUT` 保存動作を使用するよう設定することをお勧めします。そのように設定しない場合、データを復号できないことがあります。

```
DynamoDBMapperConfig mapperConfig = DynamoDBMapperConfig.builder().withSaveBehavior(SaveBehavior.PUT).build();
DynamoDBMapper mapper = new DynamoDBMapper(ddb, mapperConfig, new AttributeEncryptor(encryptor));
```

テーブルの項目でモデル化された属性のみを更新するデフォルトの保存動作を使用する場合、モデル化されていない属性は署名に含まれず、テーブルの書き込みによって変更されません。その結果、モデル化されていない属性が含まれていないため、その後のすべての属性の読み取りでは、署名は検証されません。

また、`CLOBBER` 保存動作を使用することもできます。この動作は、オプティミスティックロックを無効にしてテーブルの項目を上書きするという点を除いて、`PUT` 保存動作と同じです。

署名エラーを防ぐために、`AttributeEncryptor` が `CLOBBER` または `PUT` の保存動作で設定されていない `DynamoDBMapper` とともに使用される場合、DynamoDB Encryption Client はランタイム例外をスローします。

サンプル内で使用されているこのコードを確認するには、[DynamoDBMapper の使用](java-examples.md#java-example-dynamodb-mapper) と、GitHub の `aws-dynamodb-encryption-java` リポジトリにある [AwsKmsEncryptedObject.java](https://github.com/aws/aws-dynamodb-encryption-java/blob/master/examples/src/main/java/com/amazonaws/examples/AwsKmsEncryptedObject.java) の例を参照してください。

## Java の属性アクション
<a name="attribute-actions-java"></a>

[属性アクション](DDBEC-legacy-concepts.md#legacy-attribute-actions)では、暗号化されて署名された属性値、署名のみされた属性値、無視される属性値を指定します。属性アクションの指定に使用するメソッドは、`DynamoDBMapper` および `AttributeEncryptor`、または下位レベルの [DynamoDBEncryptor](https://aws.github.io/aws-dynamodb-encryption-java/com/amazonaws/services/dynamodbv2/datamodeling/encryption/DynamoDBEncryptor.html) の使用有無によって異なります。

**重要**  
属性アクションを使用してテーブル項目を暗号化した後、データモデルから属性を追加または削除すると、署名の検証エラーが発生し、データの復号ができなくなることがあります。詳細な説明については、「[データモデルの変更](data-model.md)」を参照してください。

### DynamoDBMapper の属性アクション
<a name="attribute-action-java-mapper"></a>

`DynamoDBMapper` および `AttributeEncryptor` を使用する場合は、注釈を使用して属性アクションを指定します。DynamoDB 暗号化クライアントは[標準の DynamoDB 属性の注釈](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBMapper.Annotations.html)を使用して、属性を保護する方法を決定する属性のタイプを定義します。デフォルトでは、プライマリキーを除く属性がすべて暗号化されます。これらの属性は署名されますが、暗号化はされません。

**注記**  
[@DynamoDBVersionAttribute 注釈](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBMapper.OptimisticLocking.html)を使用して属性値を暗号化できます。ただし、署名することはできます (署名する必要があります)。それ以外の場合、その値を使用する条件によって、意図しない結果をもたらす場合があります。

```
// Attributes are encrypted and signed
@DynamoDBAttribute(attributeName="Description")

// Partition keys are signed but not encrypted
@DynamoDBHashKey(attributeName="Title")

// Sort keys are signed but not encrypted
@DynamoDBRangeKey(attributeName="Author")
```

例外を指定するには、Java 用 Amazon DynamoDB 暗号化クライアントに定義されている暗号化注釈を使用します。クラスレベルで指定した場合は、クラスのデフォルト値になります。

```
// Sign only
@DoNotEncrypt

// Do nothing; not encrypted or signed
@DoNotTouch
```

たとえば、これらの注釈で署名するが、`PublicationYear` 属性を暗号化しない場合は、`ISBN` 属性値を暗号化または署名しないでください。

```
// Sign only (override the default)
@DoNotEncrypt
@DynamoDBAttribute(attributeName="PublicationYear")

// Do nothing (override the default)
@DoNotTouch
@DynamoDBAttribute(attributeName="ISBN")
```

### DynamoDBEncryptor の属性アクション
<a name="attribute-action-default"></a>

[DynamoDBEncryptor](https://aws.github.io/aws-dynamodb-encryption-java/com/amazonaws/services/dynamodbv2/datamodeling/encryption/DynamoDBEncryptor.html) を使用する際に属性アクションを直接指定するには、名前と値のペアで属性名と指定されたアクションを表している `HashMap` オブジェクトを作成します。

属性アクションの有効な値は、列挙型の `EncryptionFlags` で定義されています。`ENCRYPT` と `SIGN` を一緒に使用したり、`SIGN` を単独で使用したりできます。また、両方除外することもできます。ただし、`ENCRYPT` を単独で使用すると、DynamoDB 暗号化クライアントはエラーをスローします。未署名の属性を暗号化することはできません。

```
ENCRYPT
SIGN
```

**警告**  
プライマリキー属性を暗号化しないでください。DynamoDB でテーブル全体のスキャンを実行せずに項目を見つけられるように、プレーンテキストの状態を維持する必要があります。

暗号化コンテキストでプライマリキーを指定し、いずれかのプライマリキー属性の属性アクションで `ENCRYPT` を指定した場合、DynamoDB 暗号化クライアントは例外をスローします。

たとえば、次の Java コードは、`record` 項目内のすべての属性を暗号化および署名する `actions` HashMap を作成します。例外は、署名されているが暗号化されていないパーティションキー属性とソートキー属性、および署名または暗号化されていない `test` 属性です。

```
final EnumSet<EncryptionFlags> signOnly = EnumSet.of(EncryptionFlags.SIGN);
final EnumSet<EncryptionFlags> encryptAndSign = EnumSet.of(EncryptionFlags.ENCRYPT, EncryptionFlags.SIGN);
final Map<String, Set<EncryptionFlags>> actions = new HashMap<>();

for (final String attributeName : record.keySet()) {
  switch (attributeName) {
    case partitionKeyName: // no break; falls through to next case
    case sortKeyName:
      // Partition and sort keys must not be encrypted, but should be signed
      actions.put(attributeName, signOnly);
      break;
    case "test":
      // Don't encrypt or sign
      break;
    default:
      // Encrypt and sign everything else
      actions.put(attributeName, encryptAndSign);
      break;
  }
}
```

その後、`DynamoDBEncryptor` の [encryptRecord](https://aws.github.io/aws-dynamodb-encryption-java/com/amazonaws/services/dynamodbv2/datamodeling/encryption/DynamoDBEncryptor.html#encryptRecord-java.util.Map-java.util.Map-com.amazonaws.services.dynamodbv2.datamodeling.encryption.EncryptionContext-) メソッドを呼び出すときに、`attributeFlags` パラメータの値としてマップを指定します。たとえば、この `encryptRecord` の呼び出しでは、`actions` マップが使用されます。

```
// Encrypt the plaintext record
final Map<String, AttributeValue> encrypted_record = encryptor.encryptRecord(record, actions, encryptionContext);
```

## テーブル名の上書き
<a name="override-table-name"></a>

DynamoDB 暗号化クライアントでは、DynamoDB テーブルの名前は、暗号化メソッドおよび復号メソッドに渡される [DynamoDB 暗号化コンテキスト](concepts.md#encryption-context)の要素です。テーブル項目を暗号化または署名すると、テーブル名を含む DynamoDB 暗号化コンテキストが暗号化テキストに暗号でバインドされます。復号メソッドに渡される DynamoDB 暗号化コンテキストが、暗号化メソッドに渡された DynamoDB 暗号化コンテキストと一致しない場合、復号オペレーションは失敗します。

テーブルをバックアップする場合や、[ポイントインタイムリカバリ](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/PointInTimeRecovery.html)を実行する場合など、テーブルの名前が変更されることがあります。これらの項目の署名を復号または検証する際、元のテーブル名を含む、項目の暗号化と署名に使用されたのと同じ DynamoDB 暗号化コンテキストを渡す必要があります。現在のテーブル名は必要ありません。

`DynamoDBEncryptor` を使用する場合、DynamoDB 暗号化コンテキストを手動で組み立てます。ただし、`DynamoDBMapper` を使用している場合は、`AttributeEncryptor` によって現在のテーブル名を含む DynamoDB 暗号化コンテキストが作成されます。異なるテーブル名で暗号化コンテキストを作成するよう `AttributeEncryptor` に指示するには、`EncryptionContextOverrideOperator` を使用します。

たとえば、次のコードは、暗号化マテリアルプロバイダー (CMP) と `DynamoDBEncryptor` のインスタンスを作成します。次に、`DynamoDBEncryptor` の `setEncryptionContextOverrideOperator` メソッドを呼び出します。これは、1 つのテーブル名を上書きする `overrideEncryptionContextTableName` 演算子を使用します。このように設定すると、`AttributeEncryptor` によって `oldTableName` の代わりに `newTableName` を含む DynamoDB 暗号化コンテキストが作成されます。完全な例については、[EncryptionContextOverridesWithDynamoDBMapper.java](https://github.com/aws/aws-dynamodb-encryption-java/blob/master/examples/src/main/java/com/amazonaws/examples/EncryptionContextOverridesWithDynamoDBMapper.java) を参照してください。

```
final DirectKmsMaterialProvider cmp = new DirectKmsMaterialProvider(kms, keyArn);
final DynamoDBEncryptor encryptor = DynamoDBEncryptor.getInstance(cmp);

encryptor.setEncryptionContextOverrideOperator(EncryptionContextOperators.overrideEncryptionContextTableName(
                oldTableName, newTableName));
```

項目を復号および検証する `DynamoDBMapper` の load メソッドを呼び出す際、元のテーブル名を指定します。

```
mapper.load(itemClass, DynamoDBMapperConfig.builder()
                .withTableNameOverride(DynamoDBMapperConfig.TableNameOverride.withTableNameReplacement(oldTableName))
                .build());
```

また、複数のテーブル名を上書きする `overrideEncryptionContextTableNameUsingMap` 演算子を使用することもできます。

テーブル名の上書き演算子は通常、データの復号と署名の検証に使用されます。ただし、それらの演算子を使用して、暗号化および署名時に DynamoDB 暗号化コンテキスト内のテーブル名を別の値に設定することができます。

`DynamoDBEncryptor` を使用している場合は、テーブル名の上書き演算子を使用しないでください。代わりに、元のテーブル名で暗号化コンテキストを作成し、復号メソッドに送信します。

# Java 用 DynamoDB 暗号化クライアントのサンプルコード
<a name="java-examples"></a>

**注記**  
クライアント側の暗号化ライブラリの名前が [AWS Database Encryption SDK](DDBEC-rename.md) に変更されました。次のトピックには、DynamoDB Encryption Client for Java のバージョン 1.x～2.x および DynamoDB Encryption Client for Python のバージョン 1.x～3.x に関する情報が記載されています。詳細については、「[AWS Database Encryption SDK for DynamoDB バージョンのサポート](legacy-dynamodb-encryption-client.md#legacy-support)」を参照してください。

以下の例では、Java 用 DynamoDB 暗号化クライアントを使用して、アプリケーションの DynamoDB テーブル項目を保護する方法について説明します。GitHub の [aws-dynamodb-encryption-java](https://github.com/aws/aws-dynamodb-encryption-java/) リポジトリの [examples](https://github.com/aws/aws-dynamodb-encryption-java/tree/master/examples) ディレクトリに、その他の例 (および独自の使用に役立つ例) があります。

**Topics**
+ [DynamoDBEncryptor の使用](#java-example-ddb-encryptor)
+ [DynamoDBMapper の使用](#java-example-dynamodb-mapper)

## DynamoDBEncryptor の使用
<a name="java-example-ddb-encryptor"></a>

この例は、下位レベルの [DynamoDBEncryptor](https://aws.github.io/aws-dynamodb-encryption-java/com/amazonaws/services/dynamodbv2/datamodeling/encryption/DynamoDBEncryptor.html) を [Direct KMS プロバイダー](direct-kms-provider.md)で使用する方法を示しています。Direct KMS プロバイダーは、指定した [AWS KMS key](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys) in AWS Key Management Service (AWS KMS) で暗号化マテリアルを生成して保護します。

互換性のある[暗号化マテリアルプロバイダー](DDBEC-legacy-concepts.md#concept-material-provider) (CMP) を `DynamoDBEncryptor` で使用できます。また、Direct KMS プロバイダーを `DynamoDBMapper` および [AttributeEncryptor](java-using.md#attribute-encryptor) で使用できます。

**完全なコードサンプルの参照**: [AwsKmsEncryptedItem.java](https://github.com/aws/aws-dynamodb-encryption-java/blob/master/examples/src/main/java/com/amazonaws/examples/AwsKmsEncryptedItem.java)

ステップ 1: Direct KMS プロバイダーを作成する  
指定されたリージョンで AWS KMS クライアントのインスタンスを作成します。次に、クライアントインスタンスを使用して、任意の AWS KMS keyで Direct KMS プロバイダーのインスタンスを作成します。  
この例では、Amazon リソースネーム (ARN) を使用して を識別しますが AWS KMS key、[任意の有効なキー識別子](https://docs.aws.amazon.com/kms/latest/developerguide/viewing-keys.html#find-cmk-id-arn)を使用できます。  

```
final String keyArn = "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab";
final String region = "us-west-2";
      
final AWSKMS kms = AWSKMSClientBuilder.standard().withRegion(region).build();
final DirectKmsMaterialProvider cmp = new DirectKmsMaterialProvider(kms, keyArn);
```

ステップ 2: 項目を作成する  
この例では、サンプルテーブル項目を表す `record` HashMap を定義します。  

```
final String partitionKeyName = "partition_attribute";
final String sortKeyName = "sort_attribute";

final Map<String, AttributeValue> record = new HashMap<>();
record.put(partitionKeyName, new AttributeValue().withS("value1"));
record.put(sortKeyName, new AttributeValue().withN("55"));
record.put("example", new AttributeValue().withS("data"));
record.put("numbers", new AttributeValue().withN("99"));
record.put("binary", new AttributeValue().withB(ByteBuffer.wrap(new byte[]{0x00, 0x01, 0x02})));
record.put("test", new AttributeValue().withS("test-value"));
```

ステップ 3: DynamoDBEncryptor を作成する  
Direct KMS プロバイダーを使用して `DynamoDBEncryptor` のインスタンスを作成します。  

```
final DynamoDBEncryptor encryptor = DynamoDBEncryptor.getInstance(cmp);
```

ステップ 4: DynamoDB 暗号化コンテキストを作成する  
[DynamoDB 暗号化コンテキスト](concepts.md#encryption-context)には、テーブル構造に関する情報と、暗号化および署名の方法が含まれます。`DynamoDBMapper` を使用する場合は、`AttributeEncryptor` で暗号化テキストが作成されます。  

```
final String tableName = "testTable";

final EncryptionContext encryptionContext = new EncryptionContext.Builder()
    .withTableName(tableName)
    .withHashKeyName(partitionKeyName)
    .withRangeKeyName(sortKeyName)
    .build();
```

ステップ 5: 属性アクションオブジェクトを作成する  
[属性アクション](DDBEC-legacy-concepts.md#legacy-attribute-actions)では、暗号化されて署名された項目の属性値、署名のみされた項目の属性値、暗号化も署名もされていない項目の属性値を指定します。  
Java で属性アクションを指定するには、属性名と `EncryptionFlags` 値のペアの HashMap を作成します。  
たとえば、以下の Java コードでは、`actions` 項目のすべての属性を暗号化して署名する `record` HashMap を作成します。ただし、署名済みだが暗号化されていないパーティションキーおよびソートキー属性、暗号化されていない未署名の `test` 属性は除きます。  

```
final EnumSet<EncryptionFlags> signOnly = EnumSet.of(EncryptionFlags.SIGN);
final EnumSet<EncryptionFlags> encryptAndSign = EnumSet.of(EncryptionFlags.ENCRYPT, EncryptionFlags.SIGN);
final Map<String, Set<EncryptionFlags>> actions = new HashMap<>();

for (final String attributeName : record.keySet()) {
  switch (attributeName) {
    case partitionKeyName: // fall through to the next case
    case sortKeyName:
      // Partition and sort keys must not be encrypted, but should be signed
      actions.put(attributeName, signOnly);
      break;
    case "test":
      // Neither encrypted nor signed
      break;
    default:
      // Encrypt and sign all other attributes
      actions.put(attributeName, encryptAndSign);
      break;
  }
}
```

ステップ 6: 項目を暗号化および署名する  
テーブル項目を暗号化して署名するには、`encryptRecord` のインスタンスで `DynamoDBEncryptor` メソッドを呼び出します。テーブル項目 (`record`)、属性アクション (`actions`)、暗号化テキスト (`encryptionContext`) を指定します。  

```
final Map<String, AttributeValue> encrypted_record = encryptor.encryptRecord(record, actions, encryptionContext);
```

ステップ 7: DynamoDB テーブルに項目を入力する  
最後に、暗号化された署名済みの項目を DynamoDB テーブルに入力します。  

```
final AmazonDynamoDB ddb = AmazonDynamoDBClientBuilder.defaultClient();
ddb.putItem(tableName, encrypted_record);
```

## DynamoDBMapper の使用
<a name="java-example-dynamodb-mapper"></a>

以下の例は、DynamoDB マッパーヘルパークラスを [Direct KMS プロバイダー](direct-kms-provider.md)で使用する方法を示しています。Direct KMS プロバイダーは、指定した AWS Key Management Service (AWS KMS) の [AWS KMS key](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys) で暗号化マテリアルを生成して、保護します。

互換性のある[暗号化マテリアルプロバイダー](DDBEC-legacy-concepts.md#concept-material-provider) (CMP) を `DynamoDBMapper` で使用できます。また、Direct KMS プロバイダーを下位レベルの `DynamoDBEncryptor` で使用できます。

**完全なコードサンプルの参照**: [AwsKmsEncryptedObject.java](https://github.com/aws/aws-dynamodb-encryption-java/blob/master/examples/src/main/java/com/amazonaws/examples/AwsKmsEncryptedObject.java)

ステップ 1: Direct KMS プロバイダーを作成する  
指定されたリージョンで AWS KMS クライアントのインスタンスを作成します。次に、クライアントインスタンスを使用して、任意の AWS KMS keyで Direct KMS プロバイダーのインスタンスを作成します。  
この例では、Amazon リソースネーム (ARN) を使用して を識別しますが AWS KMS key、[任意の有効なキー識別子](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id)を使用できます。  

```
final String keyArn = "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab";
final String region = "us-west-2";
      
final AWSKMS kms = AWSKMSClientBuilder.standard().withRegion(region).build();
final DirectKmsMaterialProvider cmp = new DirectKmsMaterialProvider(kms, keyArn);
```

ステップ 2: DynamoDB エンクリプタと DynamoDBMapper を作成する  
前のステップで作成した Direct KMS プロバイダーを使用して、[DynamoDB エンクリプタ](java-using.md#attribute-encryptor)のインスタンスを作成します。DynamoDB マッパーを使用するには、下位レベルの DynamoDB エンクリプタをインスタンス化する必要があります。  
次に、DynamoDB データベースのインスタンスとマッパー設定を作成し、それらを使用して DynamoDB マッパーのインスタンスを作成します。  
`DynamoDBMapper` を使用して、署名された (または暗号化されて署名された) 項目を追加または編集するときは、以下の例に示されているように、`PUT` のような[保存動作を使用](java-using.md#save-behavior)するように設定して、すべての属性が含まれるようにします。そのように設定しない場合、データを復号できないことがあります。

```
final DynamoDBEncryptor encryptor = DynamoDBEncryptor.getInstance(cmp)
final AmazonDynamoDB ddb = AmazonDynamoDBClientBuilder.standard().withRegion(region).build();

DynamoDBMapperConfig mapperConfig = DynamoDBMapperConfig.builder().withSaveBehavior(SaveBehavior.PUT).build();
DynamoDBMapper mapper = new DynamoDBMapper(ddb, mapperConfig, new AttributeEncryptor(encryptor));
```

ステップ 3: DynamoDB テーブルを定義する  
次に、DynamoDB テーブルを定義します。注釈を使用して、[属性アクション](java-using.md#attribute-actions-java)を指定します。この例では、DynamoDB テーブルとして `ExampleTable` を作成し、テーブル項目を表す `DataPoJo` クラスを作成します。  
このサンプルテーブルでは、プライマリキーの属性は署名されますが、暗号化されません。これは、`@DynamoDBHashKey` という注釈が付いた `partition_attribute` に適用されます。また、`@DynamoDBRangeKey` という注釈が付いた `sort_attribute` に適用されます。  
`@DynamoDBAttribute` という注釈が付いた属性 (`some numbers` など) は暗号化されて署名されます。例外は、DynamoDB 暗号化クライアントで定義された `@DoNotEncrypt` (署名のみ) または `@DoNotTouch` (暗号化も署名もなし) 暗号化注釈を使用する属性です。たとえば、`leave me` 属性には `@DoNotTouch` 注釈が付いているため、暗号化も署名もされません。  

```
@DynamoDBTable(tableName = "ExampleTable")
public static final class DataPoJo {
  private String partitionAttribute;
  private int sortAttribute;
  private String example;
  private long someNumbers;
  private byte[] someBinary;
  private String leaveMe;

  @DynamoDBHashKey(attributeName = "partition_attribute")
  public String getPartitionAttribute() {
    return partitionAttribute;
  }

  public void setPartitionAttribute(String partitionAttribute) {
    this.partitionAttribute = partitionAttribute;
  }

  @DynamoDBRangeKey(attributeName = "sort_attribute")
  public int getSortAttribute() {
    return sortAttribute;
  }

  public void setSortAttribute(int sortAttribute) {
    this.sortAttribute = sortAttribute;
  }

  @DynamoDBAttribute(attributeName = "example")
  public String getExample() {
    return example;
  }

  public void setExample(String example) {
    this.example = example;
  }

  @DynamoDBAttribute(attributeName = "some numbers")
  public long getSomeNumbers() {
    return someNumbers;
  }

  public void setSomeNumbers(long someNumbers) {
    this.someNumbers = someNumbers;
  }

  @DynamoDBAttribute(attributeName = "and some binary")
  public byte[] getSomeBinary() {
    return someBinary;
  }

  public void setSomeBinary(byte[] someBinary) {
    this.someBinary = someBinary;
  }

  @DynamoDBAttribute(attributeName = "leave me")
  @DoNotTouch
  public String getLeaveMe() {
    return leaveMe;
  }

  public void setLeaveMe(String leaveMe) {
    this.leaveMe = leaveMe;
  }

  @Override
  public String toString() {
    return "DataPoJo [partitionAttribute=" + partitionAttribute + ", sortAttribute="
        + sortAttribute + ", example=" + example + ", someNumbers=" + someNumbers
        + ", someBinary=" + Arrays.toString(someBinary) + ", leaveMe=" + leaveMe + "]";
  }
}
```

ステップ 4: テーブル項目を暗号化して保存する  
これで、テーブル項目を作成し、DynamoDB マッパーを使用して項目を保存すると、項目はテーブルに追加される前に自動的に暗号化されて署名されます。  
この例では、`record` というテーブル項目を定義しています。この項目がテーブルに保存される前に、`DataPoJo` クラスの注釈に基づいて、その属性は暗号化されて署名されます。この場合、`PartitionAttribute`、`SortAttribute`、`LeaveMe` を除くすべての属性が暗号化されて署名されます。`PartitionAttribute` と `SortAttributes` は署名のみされます。`LeaveMe` 属性は暗号化または署名されていません。  
`record` 項目を暗号化して署名し、`ExampleTable` に追加するには、`DynamoDBMapper` クラスの `save` メソッドを呼び出します。DynamoDB マッパーは `PUT` 保存動作を使用するように設定されているため、項目は更新されず、代わりに同じプライマリキーを使用する項目に置き換えられます。これにより、確実に署名が一致するようになり、その項目をテーブルからの取得時に復号化できます。  

```
DataPoJo record = new DataPoJo();
record.setPartitionAttribute("is this");
record.setSortAttribute(55);
record.setExample("data");
record.setSomeNumbers(99);
record.setSomeBinary(new byte[]{0x00, 0x01, 0x02});
record.setLeaveMe("alone");

mapper.save(record);
```