

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

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