

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

# AWS Database Encryption SDK for DynamoDB
<a name="dynamodb-encryption-client"></a>


****  

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

 AWS Database Encryption SDK for DynamoDB は、[Amazon DynamoDB ](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/)設計にクライアント側の暗号化を含めることができるソフトウェアライブラリです。 AWS Database Encryption SDK for DynamoDB は属性レベルの暗号化を提供し、暗号化する項目と、データの信頼性を保証する署名に含める項目を指定できます。伝送中および保管時の機密データを暗号化することで、 AWSなどのサードパーティーがお客様のプレーンテキストデータを使用することはできません。

**注記**  
 AWS Database Encryption SDK は PartiQL をサポートしていません。

DynamoDB では、[テーブル](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.CoreComponents.html#HowItWorks.CoreComponents.TablesItemsAttributes)は項目のコレクションです。各*項目*は、*属性*の集合です。各属性には名前と値があります。 AWS Database Encryption SDK for DynamoDB は、属性の値を暗号化します。次に、属性に対する署名を計算します。[暗号化アクション](concepts.md#crypt-actions)でどの属性値を暗号化し、署名にどの属性値を含めるかを指定します。

この章のトピックでは、暗号化されるフィールド、クライアントのインストールと設定に関するガイダンス、開始に役立つ Java の例など、 AWS Database Encryption SDK for DynamoDB の概要について説明します。

**Topics**
+ [クライアント側とサーバー側の暗号化](client-server-side.md)
+ [どのフィールドが暗号化および署名されますか?](DDB-encrypted-and-signed.md)
+ [DynamoDB での検索可能な暗号化](ddb-searchable-encryption.md)
+ [データモデルの更新](ddb-update-data-model.md)
+ [AWS Database Encryption SDK for DynamoDB で利用可能なプログラミング言語](ddb-programming-languages.md)
+ [レガシー DynamoDB 暗号化クライアント](legacy-dynamodb-encryption-client.md)

# クライアント側とサーバー側の暗号化
<a name="client-server-side"></a>


****  

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

 AWS Database Encryption SDK for DynamoDB は、テーブルデータをデータベースに送信する前に暗号化する*クライアント側の暗号化*をサポートしています。ただし、DynamoDB では、ディスクに保管されているテーブルを透過的に暗号化するサーバー側の*保管時の暗号化*機能を提供しており、ユーザーがテーブルにアクセスすると復号します。

選択するツールは、データの重要度と、アプリケーションのセキュリティ要件に応じて異なります。 AWS Database Encryption SDK for DynamoDB と保管時の暗号化の両方を使用できます。暗号化されて署名された項目を DynamoDB に送信しても、保護されている項目は DynamoDB によって認識されません。バイナリ属性値を含む従来のテーブル項目を検出します。

**サーバー側の保管時の暗号化**

DynamoDB では、[保管時の暗号化](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/EncryptionAtRest.html)がサポートされています。これは、テーブルがディスクに保持されるときに DynamoDB がテーブルを透過的に暗号化し、ユーザーがテーブルデータにアクセスするときにテーブルを復号する*サーバー側の暗号化*機能です。

 AWS SDK を使用して DynamoDB を操作する場合、デフォルトでは、データは HTTPS 接続を介して転送中に暗号化され、DynamoDB エンドポイントで復号され、DynamoDB に保存される前に再暗号化されます。
+ **デフォルトでの暗号化。**DynamoDB は、書き込まれる際に、すべてのテーブルを透過的に暗号化および復号します。保管時の暗号化を有効または無効にするオプションはありません。
+ **DynamoDB は暗号化キーを作成および管理します。**各テーブルの一意のキーは、[AWS KMS key](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys) で保護されるため、[AWS Key Management Service](https://docs.aws.amazon.com/kms/latest/developerguide/) (AWS KMS) が未暗号化のままになることはありません。デフォルトでは、DynamoDB は DynamoDB サービス アカウントの [AWS 所有のキー](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#aws-owned-cmk) を使用しますが、一部またはすべてのテーブルを保護するために、自分のアカウントの [AWS マネージドキー](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#aws-managed-cmk) または[カスタマーマネージドキー](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#customer-cmk)を選択することもできます。
+ **テーブルデータはすべて、ディスク上で暗号化されます。**暗号化されたテーブルがディスクに保存されると、DynamoDB は、[プライマリキー](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.CoreComponents.html#HowItWorks.CoreComponents.PrimaryKey)およびローカルとグローバルの[セカンダリインデックス](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.CoreComponents.html#HowItWorks.CoreComponents.SecondaryIndexes)など、すべてのテーブルデータを暗号化します。テーブルにソートキーが存在する場合、範囲の境界線を示すソートキーの一部が、プレーンテキスト形式でテーブルメタデータに保存されます。
+ **テーブルに関連するオブジェクトも暗号化されます。**保管時の暗号化は、永続的なメディアに書き込まれるたびに、[DynamoDBストリーム](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Streams.html)、[グローバルテーブル](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GlobalTables.html)、[バックアップ](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/BackupRestore.html)を保護します。
+ **アクセスすると、項目は復号されます。**テーブルがアクセスされるとき、DynamoDB は、ターゲット項目を含むテーブル部分を復号し、プレーンテキスト形式で項目を返します。

**AWS Database Encryption SDK for DynamoDB**

クライアント側の暗号化では、ソースから DynamoDB のストレージまで、伝送時および保管時のデータをエンドツーエンド保護します。プレーンテキストデータは、以下を含む第三者に公開されることはありません AWS。 AWS Database Encryption SDK for DynamoDB を新しい DynamoDB テーブルで使用するか、既存の Amazon DynamoDB テーブルを AWS Database Encryption SDK for DynamoDB の最新バージョンに移行できます。
+ **転送時と保管時のデータは保護されます。**以下を含む第三者に公開されることはありません AWS。
+ **テーブル項目に署名できます。**プライマリキー属性など、テーブル項目のすべてまたは一部の署名を計算するように、 AWS Database Encryption SDK for DynamoDB に指示できます。この署名により、属性の追加や削除、属性値のスワップなど、項目全体への不正な変更を検出することができます。
+ [キーリングを選択](keyrings.md)することで、**データを保護する方法を決定**します。キーリングは、データキー、そして最終的にはデータを保護するラッピングキーを決定します。タスクに実用的で、最も安全なラッピングキーを使用してください。
+ ** AWS Database Encryption SDK for DynamoDB はテーブル全体を暗号化しません。**項目内でどの属性を暗号化するかを選択します。 AWS Database Encryption SDK for DynamoDB は項目全体を暗号化しません。属性名、プライマリキー (パーティションキーおよびソートキー) 属性の名前または値は暗号化されません。

**AWS Encryption SDK**

DynamoDB に保存するデータを暗号化する場合は、 AWS Database Encryption SDK for DynamoDB をお勧めします。

[AWS Encryption SDK](https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/) は、クライアント側暗号化ライブラリで、汎用データの暗号化および復号に役立ちます。任意のタイプのデータを保護することはできますが、データベースレコードなどの構造化データは操作できません。 AWS Database Encryption SDK for DynamoDB とは異なり、 は項目レベルの整合性チェックを提供 AWS Encryption SDK できず、属性を認識したり、プライマリキーの暗号化を防ぐロジックはありません。

を使用してテーブルの要素を AWS Encryption SDK 暗号化する場合は、 AWS Database Encryption SDK for DynamoDB と互換性がないことに注意してください。1 つのライブラリで暗号化し、もう 1 つのライブラリを使用して復号することはできません。

# どのフィールドが暗号化および署名されますか?
<a name="DDB-encrypted-and-signed"></a>


****  

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

 AWS Database Encryption SDK for DynamoDB は、特に Amazon DynamoDB アプリケーション用に設計されたクライアント側の暗号化ライブラリです。Amazon DynamoDB は、項目のコレクションである[テーブル](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.CoreComponents.html#HowItWorks.CoreComponents.TablesItemsAttributes)にデータを格納します。各*項目*は、*属性*の集合です。各属性には名前と値があります。 AWS Database Encryption SDK for DynamoDB は、属性の値を暗号化します。次に、属性に対する署名を計算します。暗号化される属性値、および署名に含めるか指定できます。

暗号化は、属性値の機密保持を保護します。署名は、署名されたすべての属性とその相互の関係を保全し、認証を提供します。これにより、属性の追加や削除、暗号化された値の別の値への置換など、項目全体への不正な変更を検出することができます。

暗号化された項目では、テーブル名、すべての属性名、暗号化していない属性値、プライマリキー (パーティションキーとソートキー) 属性の名前と値、属性タイプなど、一部のデータはプレーンテキストで残ります。これらのフィールドに機密データを保存しないでください。

 AWS Database Encryption SDK for DynamoDB の仕組みの詳細については、「」を参照してください[AWS Database Encryption SDK の仕組み](how-it-works.md)。

**注記**  
 AWS Database Encryption SDK for DynamoDB トピックの*属性アクション*に関するすべての言及は、[暗号化アクション](concepts.md#crypt-actions)を指します。

**Topics**
+ [暗号化の属性値](#encrypt-attribute-values)
+ [項目の署名](#sign-the-item)

## 暗号化の属性値
<a name="encrypt-attribute-values"></a>

 AWS Database Encryption SDK for DynamoDB は、指定した属性の値 (属性名またはタイプではありません) を暗号化します。どの属性値が暗号化されているかを確認するには、[属性アクション](concepts.md#crypt-actions)を使用します。

たとえば、この項目には `example` および `test` 属性が含まれます。

```
'example': 'data',
'test': 'test-value',
...
```

`example` 属性を暗号化し、`test` 属性を暗号化しない場合、結果は次のようになります。暗号化された `example` 属性値は、文字列ではなくバイナリデータです。

```
'example': Binary(b"'b\x933\x9a+s\xf1\xd6a\xc5\xd5\x1aZ\xed\xd6\xce\xe9X\xf0T\xcb\x9fY\x9f\xf3\xc9C\x83\r\xbb\\"),
'test': 'test-value'
...
```

各項目のプライマリキー属性 (パーティションキーおよびソートキー) を使用して DynamoDB はテーブル内の項目を検索するため、それらの属性はプレーンテキストのままである必要があります。署名は必要ですが、暗号化の必要はありません。

 AWS Database Encryption SDK for DynamoDB は、プライマリキー属性を識別し、その値が署名されているが暗号化されていないことを確認します。また、プライマリキーを特定してそれを暗号化しようとすると、クライアントは例外をスローします。

クライアントは、項目に追加する新しい属性 (`aws_dbe_head`) に[マテリアルの説明](concepts.md#material-description)を格納します。マテリアルの説明は、項目がどのように暗号化および署名されたかを説明するものです。クライアントは、この情報を使用して項目の検証と復号を行います。マテリアルの説明を格納するフィールドは暗号化されません。

## 項目の署名
<a name="sign-the-item"></a>

指定された属性値を暗号化した後、 AWS Database Encryption SDK for DynamoDB は、マテリアルの説明、[暗号化コンテキスト](concepts.md#encryption-context)、および[属性アクション](concepts.md#crypt-actions)`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`で `ENCRYPT_AND_SIGN`、`SIGN_ONLY`、または とマークされた各フィールドの正規化にわたって、ハッシュベースのメッセージ認証コード (HMACs) と[デジタル署名](concepts.md#digital-sigs)を計算します。ECDSA 署名はデフォルトで有効になっていますが、必須ではありません。クライアントは、項目に追加する新しい属性 (`aws_dbe_foot`) に HMAC と署名を格納します。

# DynamoDB での検索可能な暗号化
<a name="ddb-searchable-encryption"></a>

検索可能な暗号化のために Amazon DynamoDB テーブルを設定するには、[AWS KMS 階層キーリング](use-hierarchical-keyring.md)を使用して、項目を保護するために使用されるデータキーを生成、暗号化、および復号する必要があります。また、テーブル暗号化設定に [`SearchConfig`](ddb-net-using.md#ddb-net-search-config) を含める必要があります。

**注記**  
DynamoDB 用の Java クライアント側の暗号化ライブラリを使用している場合は、低レベルの AWS Database Encryption SDK for DynamoDB API を使用して、テーブル項目を暗号化、署名、検証、復号化する必要があります。DynamoDB Enhanced Client と下位レベルの `DynamoDBItemEncryptor` は、検索可能な暗号化をサポートしていません。

**Topics**
+ [ビーコンを使用したセカンダリインデックスの設定](#ddb-beacon-indexes)
+ [ビーコン出力のテスト](#ddb-beacon-testing)

## ビーコンを使用したセカンダリインデックスの設定
<a name="ddb-beacon-indexes"></a>

[ビーコンを設定](configure-beacons.md)した後、暗号化された属性を検索する前に、各ビーコンを反映するセカンダリインデックスを設定する必要があります。

標準ビーコンまたは複合ビーコンを設定すると、 AWS Database Encryption SDK はビーコン名に`aws_dbe_b_`プレフィックスを追加して、サーバーがビーコンを簡単に識別できるようにします。例えば、複合ビーコンに `compoundBeacon` という名前を付けた場合、実際の完全なビーコン名は `aws_dbe_b_compoundBeacon` です。標準ビーコンまたは複合ビーコンを含む[セカンダリインデックス](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/SecondaryIndexes.html)を設定する場合は、ビーコン名を識別するときに `aws_dbe_b_` プレフィックスを含める必要があります。

**パーティションキーとソートキー**  
プライマリキーの値を暗号化することはできません。パーティションキーとソートキーは署名されている必要があります。プライマリキーの値を標準ビーコンまたは複合ビーコンにすることはできません。  
属性を指定しない限り`SIGN_ONLY`、プライマリキーの値は である必要があります。`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`パーティション属性とソート属性も である必要があります`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`。  
プライマリキーの値を署名付きビーコンにすることができます。プライマリキーの値ごとに個別の署名付きビーコンを設定した場合は、プライマリキーの値を識別する属性名を署名付きビーコン名として指定する必要があります。ただし、 AWS Database Encryption SDK は署名付きビーコンに`aws_dbe_b_`プレフィックスを追加しません。プライマリキーの値に個別の署名付きビーコンを設定した場合でも、必要なのは、セカンダリインデックスを設定する際に、プライマリキーの値の属性名を指定することだけです。

**ローカルセカンダリインデックス**  
[ローカルセカンダリインデックス](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LSI.html)のソートキーはビーコンにすることができます。  
ソートキーにビーコンを指定する場合、タイプは String である必要があります。ソートキーに標準ビーコンまたは複合ビーコンを指定する場合は、ビーコン名を指定する際に `aws_dbe_b_` プレフィックスを含める必要があります。署名付きビーコンを指定する場合は、プレフィックスなしでビーコン名を指定します。

**グローバルセカンダリインデックス**  
[グローバルセカンダリインデックス](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GSI.html)のパーティションキーとソートキーは両方ともビーコンにすることができます。  
パーティションキーまたはソートキーにビーコンを指定する場合、タイプは String である必要があります。ソートキーに標準ビーコンまたは複合ビーコンを指定する場合は、ビーコン名を指定する際に `aws_dbe_b_` プレフィックスを含める必要があります。署名付きビーコンを指定する場合は、プレフィックスなしでビーコン名を指定します。

**属性の射影**  
[射影](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GSI.html#GSI.Projections)とは、テーブルからセカンダリインデックスにコピーされる属性のセットです。テーブルのパーティションキーとソートキーは常にインデックスに射影されます。アプリケーションのクエリ要件をサポートするために、他の属性を射影できます。DynamoDB は、属性プロジェクションのために、`KEYS_ONLY`、`INCLUDE`、`ALL` の 3 つの異なるオプションを提供します。  
INCLUDE 属性プロジェクションを使用してビーコンを検索する場合は、ビーコンが構築されるすべての属性の名前と、`aws_dbe_b_` プレフィックスを持つビーコン名を指定する必要があります。例えば、`field1`、`field2`、および `field3` から複合ビーコン `compoundBeacon` を設定した場合、プロジェクション内で、`aws_dbe_b_compoundBeacon`、`field1`、`field2`、`field3` を指定する必要があります。  
グローバルセカンダリインデックスはプロジェクションで明示的に指定された属性のみを使用できますが、ローカルセカンダリインデックスは任意の属性を使用できます。

## ビーコン出力のテスト
<a name="ddb-beacon-testing"></a>

[複合ビーコンを設定](configure-beacons.md#config-compound-beacons)した場合、または[仮想フィールド](configure-beacons.md#create-virtual-field)を使用してビーコンを構築した場合は、DynamoDB テーブルに入力する前に、これらのビーコンが期待される出力を生成することを確認することをお勧めします。

 AWS Database Encryption SDK は、仮想フィールドと複合ビーコン出力のトラブルシューティングに役立つ `DynamoDbEncryptionTransforms`サービスを提供します。

### 仮想フィールドのテスト
<a name="ddb-beacon-testing-virtual-field"></a>

次のスニペットは、テスト項目を作成し、[DynamoDB テーブル暗号化設定](ddb-java-using.md#ddb-config-encrypt)を使用して`DynamoDbEncryptionTransforms`サービスを定義し、 `ResolveAttributes` を使用して仮想フィールドが期待される出力を生成することを確認する方法を示しています。

------
#### [ Java ]

**完全なコードサンプルを参照**: [VirtualBeaconSearchableEncryptionExample.java](https://github.com/aws/aws-database-encryption-sdk-dynamodb//blob/main/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/searchableencryption/VirtualBeaconSearchableEncryptionExample.java) 

```
// Create test items
final PutItemRequest itemWithHasTestResultPutRequest = PutItemRequest.builder()
    .tableName(ddbTableName)
    .item(itemWithHasTestResult)
    .build();

final PutItemResponse itemWithHasTestResultPutResponse = ddb.putItem(itemWithHasTestResultPutRequest);

final PutItemRequest itemWithNoHasTestResultPutRequest = PutItemRequest.builder()
    .tableName(ddbTableName)
    .item(itemWithNoHasTestResult)
    .build();
    
final PutItemResponse itemWithNoHasTestResultPutResponse = ddb.putItem(itemWithNoHasTestResultPutRequest);    

// Define the DynamoDbEncryptionTransforms service
final DynamoDbEncryptionTransforms trans = DynamoDbEncryptionTransforms.builder()
    .DynamoDbTablesEncryptionConfig(encryptionConfig).build();

// Verify configuration
final ResolveAttributesInput resolveInput = ResolveAttributesInput.builder()
    .TableName(ddbTableName)
    .Item(itemWithHasTestResult)
    .Version(1)
    .build();
final ResolveAttributesOutput resolveOutput = trans.ResolveAttributes(resolveInput);

// Verify that VirtualFields has the expected value
Map<String, String> vf = new HashMap<>();
vf.put("stateAndHasTestResult", "CAt");
assert resolveOutput.VirtualFields().equals(vf);
```

------
#### [ C\$1 / .NET ]

**完全なコードサンプル**「[VirtualBeaconSearchableEncryptionExample.cs](https://github.com/aws/aws-database-encryption-sdk-dynamodb/tree/main/Examples/runtimes/net/src/searchableencryption/VirtualBeaconSearchableEncryptionExample.cs)」を参照してください。

```
 // Create item with hasTestResult=true
var itemWithHasTestResult = new Dictionary<String, AttributeValue>
{
    ["customer_id"] = new AttributeValue("ABC-123"),
    ["create_time"] = new AttributeValue { N = "1681495205" },
    ["state"] = new AttributeValue("CA"),
    ["hasTestResult"] = new AttributeValue { BOOL = true }
};

// Create item with hasTestResult=false
var itemWithNoHasTestResult = new Dictionary<String, AttributeValue>
{
    ["customer_id"] = new AttributeValue("DEF-456"),
    ["create_time"] = new AttributeValue { N = "1681495205" },
    ["state"] = new AttributeValue("CA"),
    ["hasTestResult"] = new AttributeValue { BOOL = false }
};

// Define the DynamoDbEncryptionTransforms service
var trans = new DynamoDbEncryptionTransforms(encryptionConfig);

// Verify configuration
var resolveInput = new ResolveAttributesInput
{
    TableName = ddbTableName,
    Item = itemWithHasTestResult,
    Version = 1
};
var resolveOutput = trans.ResolveAttributes(resolveInput);

// Verify that VirtualFields has the expected value
Debug.Assert(resolveOutput.VirtualFields.Count == 1);
Debug.Assert(resolveOutput.VirtualFields["stateAndHasTestResult"] == "CAt");
```

------
#### [ Rust ]

**完全なコードサンプル**[「virtual\$1beacon\$1searchable\$1encryption.rs](https://github.com/aws/aws-database-encryption-sdk-dynamodb/blob/main/releases/rust/db_esdk/examples/searchableencryption/virtual_beacon_searchable_encryption.rs)」を参照してください。

```
// Create item with hasTestResult=true
let item_with_has_test_result = HashMap::from([
    (
        "customer_id".to_string(),
        AttributeValue::S("ABC-123".to_string()),
    ),
    (
        "create_time".to_string(),
        AttributeValue::N("1681495205".to_string()),
    ),
    ("state".to_string(), AttributeValue::S("CA".to_string())),
    ("hasTestResult".to_string(), AttributeValue::Bool(true)),
]);

// Create item with hasTestResult=false
let item_with_no_has_test_result = HashMap::from([
    (
        "customer_id".to_string(),
        AttributeValue::S("DEF-456".to_string()),
    ),
    (
        "create_time".to_string(),
        AttributeValue::N("1681495205".to_string()),
    ),
    ("state".to_string(), AttributeValue::S("CA".to_string())),
    ("hasTestResult".to_string(), AttributeValue::Bool(false)),
]);

// Define the transform service
let trans = transform_client::Client::from_conf(encryption_config.clone())?;

// Verify the configuration 
let resolve_output = trans
    .resolve_attributes()
    .table_name(ddb_table_name)
    .item(item_with_has_test_result.clone())
    .version(1)
    .send()
    .await?;

// Verify that VirtualFields has the expected value
let virtual_fields = resolve_output.virtual_fields.unwrap();
assert_eq!(virtual_fields.len(), 1);
assert_eq!(virtual_fields["stateAndHasTestResult"], "CAt");
```

------

### 複合ビーコンのテスト
<a name="ddb-beacon-testing-compound-beacon"></a>

次のスニペットでは、テスト項目を作成し、[DynamoDB テーブル暗号化設定](ddb-java-using.md#ddb-config-encrypt)を使用して`DynamoDbEncryptionTransforms`サービスを定義し、 `ResolveAttributes`を使用して複合ビーコンが期待される出力を生成することを確認する方法を示します。

------
#### [ Java ]

**完全なコードサンプルを参照**: [CompoundBeaconSearchableEncryptionExample.java](https://github.com/aws/aws-database-encryption-sdk-dynamodb//blob/main/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/searchableencryption/CompoundBeaconSearchableEncryptionExample.java) 

```
// Create an item with both attributes used in the compound beacon.
final HashMap<String, AttributeValue> item = new HashMap<>();
item.put("work_id", AttributeValue.builder().s("9ce39272-8068-4efd-a211-cd162ad65d4c").build());
item.put("inspection_date", AttributeValue.builder().s("2023-06-13").build());
item.put("inspector_id_last4", AttributeValue.builder().s("5678").build());
item.put("unit", AttributeValue.builder().s("011899988199").build());
                            
// Define the DynamoDbEncryptionTransforms service
final DynamoDbEncryptionTransforms trans = DynamoDbEncryptionTransforms.builder()
    .DynamoDbTablesEncryptionConfig(encryptionConfig).build();

// Verify configuration 
final ResolveAttributesInput resolveInput = ResolveAttributesInput.builder()
    .TableName(ddbTableName)
    .Item(item)
    .Version(1)
    .build();

final ResolveAttributesOutput resolveOutput = trans.ResolveAttributes(resolveInput);
                            
// Verify that CompoundBeacons has the expected value   
Map<String, String> cbs = new HashMap<>();
cbs.put("last4UnitCompound", "L-5678.U-011899988199");
assert resolveOutput.CompoundBeacons().equals(cbs);
// Note : the compound beacon actually stored in the table is not "L-5678.U-011899988199"
// but rather something like "L-abc.U-123", as both parts are EncryptedParts
// and therefore the text is replaced by the associated beacon
```

------
#### [ C\$1 / .NET ]

**完全なコードサンプルを参照**: [CompoundBeaconSearchableEncryptionExample.cs](https://github.com/aws/aws-database-encryption-sdk-dynamodb/tree/main/Examples/runtimes/net/src/searchableencryption/CompoundBeaconSearchableEncryptionExample.cs)

```
// Create an item with both attributes used in the compound beacon
var item = new Dictionary<String, AttributeValue>
{
    ["work_id"] = new AttributeValue("9ce39272-8068-4efd-a211-cd162ad65d4c"),
    ["inspection_date"] = new AttributeValue("2023-06-13"),
    ["inspector_id_last4"] = new AttributeValue("5678"),
    ["unit"] = new AttributeValue("011899988199")
};                           
                            
// Define the DynamoDbEncryptionTransforms service
var trans = new DynamoDbEncryptionTransforms(encryptionConfig);

// Verify configuration
var resolveInput = new ResolveAttributesInput
{
    TableName = ddbTableName,
    Item = item,
    Version = 1
};
var resolveOutput = trans.ResolveAttributes(resolveInput);                            
                            
// Verify that CompoundBeacons has the expected value 
Debug.Assert(resolveOutput.CompoundBeacons.Count == 1);
Debug.Assert(resolveOutput.CompoundBeacons["last4UnitCompound"] == "L-5678.U-011899988199");
// Note : the compound beacon actually stored in the table is not "L-5678.U-011899988199"
// but rather something like "L-abc.U-123", as both parts are EncryptedParts
// and therefore the text is replaced by the associated beacon
```

------
#### [ Rust ]

**完全なコードサンプルを参照**: [compound\$1beacon\$1searchable\$1encryption.rs](https://github.com/aws/aws-database-encryption-sdk-dynamodb/blob/main/releases/rust/db_esdk/examples/searchableencryption/compound_beacon_searchable_encryption.rs)

```
// Create an item with both attributes used in the compound beacon
let item = HashMap::from([
    (
        "work_id".to_string(),
        AttributeValue::S("9ce39272-8068-4efd-a211-cd162ad65d4c".to_string()),
    ),
    (
        "inspection_date".to_string(),
        AttributeValue::S("2023-06-13".to_string()),
    ),
    (
        "inspector_id_last4".to_string(),
        AttributeValue::S("5678".to_string()),
    ),
    (
        "unit".to_string(),
        AttributeValue::S("011899988199".to_string()),
    ),
]);                           
                            
// Define the transforms service
let trans = transform_client::Client::from_conf(encryption_config.clone())?;

// Verify configuration
let resolve_output = trans
    .resolve_attributes()
    .table_name(ddb_table_name)
    .item(item.clone())
    .version(1)
    .send()
    .await?;                            
                            
// Verify that CompoundBeacons has the expected value 
let compound_beacons = resolve_output.compound_beacons.unwrap();
assert_eq!(compound_beacons.len(), 1);
assert_eq!(
    compound_beacons["last4UnitCompound"],
    "L-5678.U-011899988199"
);
// but rather something like "L-abc.U-123", as both parts are EncryptedParts
// and therefore the text is replaced by the associated beacon
```

------

# データモデルの更新
<a name="ddb-update-data-model"></a>


****  

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

Database AWS Encryption SDK for DynamoDB を設定するときは、[属性アクション](concepts.md#crypt-actions)を指定します。暗号化では、 AWS データベース暗号化 SDK は 属性アクションを使用して、暗号化して署名する属性、署名する (暗号化しない) 属性、無視する属性を識別します。また、[許可された署名なし属性](ddb-java-using.md#allowed-unauth)を定義して、どの属性が署名から除外されるかをクライアントに明示的に伝えます。復号時に、 AWS Database Encryption SDK は、定義した許可された署名なし属性を使用して、署名に含まれていない属性を識別します。属性アクションは暗号化された項目に保存されず、 AWS Database Encryption SDK は属性アクションを自動的に更新しません。

属性アクションを慎重に選択します。不確かな場合は、**暗号化と署名**を使用します。 AWS Database Encryption SDK を使用して項目を保護すると、既存の `ENCRYPT_AND_SIGN`、`SIGN_ONLY`、または `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 属性を に変更することはできません`DO_NOTHING`。ただし、次の変更は安全に行うことができます。
+ [新しい `ENCRYPT_AND_SIGN`、`SIGN_ONLY`、および `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 属性を追加する](#ddb-add-auth-attribute)
+ [既存の属性を削除する](#ddb-remove-attribute)
+ [既存の`ENCRYPT_AND_SIGN`属性を `SIGN_ONLY`または に変更する `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`](#ddb-encrypt-to-sign)
+ [既存の `SIGN_ONLY`または `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 属性を に変更する `ENCRYPT_AND_SIGN`](#ddb-sign-to-encrypt)
+ [新しい `DO_NOTHING` 属性を追加する](#ddb-add-unauth-attribute)
+ [既存の `SIGN_ONLY` 属性を `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` に変更する](#ddb-signOnly-to-signInclude)
+ [既存の `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 属性を `SIGN_ONLY` に変更する](#ddb-signInclude-to-signOnly)

**検索可能な暗号化に関する考慮事項**  
データモデルを更新する前に、属性から構築した[ビーコン](beacons.md)に対して、その更新がどのような影響を及ぼす可能性があるかを慎重に検討してください。ビーコンを持つ新しいレコードを書き込んだ後に、そのビーコンの設定を更新することはできません。ビーコンを構築するために使用した属性に関連付けられた属性アクションを更新することはできません。既存の属性とそれに関連付けられたビーコンを削除すると、そのビーコンを使用して既存のレコードをクエリできなくなります。レコードに追加する新しいフィールドについての新しいビーコンを作成することはできますが、既存のビーコンを更新して新しいフィールドを含めることはできません。

**`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 属性に関する考慮事項**  
デフォルトでは、パーティションキーとソートキーは、暗号化コンテキストに含まれる唯一の属性です。[AWS KMS 階層キーリング](use-hierarchical-keyring.md)のブランチキー ID サプライヤーが暗号化コンテキストからの復号に必要なブランチキーを特定`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`できるように、追加のフィールドを として定義することを検討してください。詳細については、[「ブランチキー ID サプライヤー](use-hierarchical-keyring.md#branch-key-id-supplier)」を参照してください。`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 属性を指定する場合、パーティション属性とソート属性も である必要があります`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`。

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

## 新しい `ENCRYPT_AND_SIGN`、`SIGN_ONLY`、および `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 属性を追加する
<a name="ddb-add-auth-attribute"></a>

新しい `ENCRYPT_AND_SIGN`、`SIGN_ONLY`、または `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 属性を追加するには、属性アクションで新しい属性を定義します。

既存の`DO_NOTHING`属性を削除して、`ENCRYPT_AND_SIGN`、`SIGN_ONLY`、または `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 属性として再度追加することはできません。

**アノテーション付きデータクラスの使用**  
`TableSchema` を使用して属性アクションを定義した場合は、新しい属性をアノテーション付きデータクラスに追加します。新しい属性の属性アクションのアノテーションを指定しない場合、クライアントは、デフォルトで新しい属性を暗号化して署名します (属性がプライマリキーの一部である場合を除きます)。新しい属性のみに署名する場合は、 `@DynamoDBEncryptionSignOnly`または `@DynamoDBEncryptionSignAndIncludeInEncryptionContext`注釈で新しい属性を追加する必要があります。

**オブジェクトモデルの使用**  
属性アクションを手動で定義した場合は、オブジェクトモデルの属性アクションに新しい属性を追加し、属性アクション`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`として `ENCRYPT_AND_SIGN`、`SIGN_ONLY`、または を指定します。

## 既存の属性を削除する
<a name="ddb-remove-attribute"></a>

属性が必要なくなったと判断した場合は、その属性に対するデータの書き込みを停止することも、属性アクションから正式に削除することもできます。属性に対する新しいデータの書き込みを停止しても、その属性は引き続き属性アクションに表示されます。これは、将来再び属性の使用を開始する必要がある場合に役立ちます。属性アクションから属性を正式に削除しても、データセットからは削除されません。データセットには、その属性を含む項目が引き続き含まれます。

既存の `ENCRYPT_AND_SIGN`、`SIGN_ONLY`、`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`、または `DO_NOTHING` 属性を正式に削除するには、属性アクションを更新します。

`DO_NOTHING` 属性を削除する場合でも、[許可された署名なし属性](ddb-java-using.md#allowed-unauth)からその属性を削除しないでください。その属性に対して新しい値を書き込まなくなった場合でも、クライアントは、その属性を含む既存の項目を読み取るために、その属性が署名されていないことを認識する必要があります。

**アノテーション付きデータクラスの使用**  
`TableSchema` を使用して属性アクションを定義した場合は、アノテーション付きデータクラスからその属性を削除します。

**オブジェクトモデルの使用**  
属性アクションを手動で定義した場合は、オブジェクトモデルの属性アクションから属性を削除します。

## 既存の`ENCRYPT_AND_SIGN`属性を `SIGN_ONLY`または に変更する `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`
<a name="ddb-encrypt-to-sign"></a>

既存の`ENCRYPT_AND_SIGN`属性を `SIGN_ONLY`または に変更するには`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`、属性アクションを更新する必要があります。更新をデプロイした後、クライアントは属性に書き込まれた既存の値を検証して復号できるようになりますが、実行するアクションは属性に対して書き込まれた新しい値に署名することだけです。

**注記**  
既存の`ENCRYPT_AND_SIGN`属性を `SIGN_ONLY`または に変更する前に、セキュリティ要件を慎重に検討してください`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`。機密データを保存できる属性はすべて暗号化する必要があります。

**アノテーション付きデータクラスの使用**  
で属性アクションを定義した場合は`TableSchema`、既存の属性を更新して、注釈付きデータクラスに `@DynamoDBEncryptionSignOnly`または `@DynamoDBEncryptionSignAndIncludeInEncryptionContext`注釈を含めます。

**オブジェクトモデルの使用**  
属性アクションを手動で定義した場合は、既存の属性に関連付けられた属性アクションを オブジェクトモデル`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`で から `SIGN_ONLY`または `ENCRYPT_AND_SIGN` に更新します。

## 既存の `SIGN_ONLY`または `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 属性を に変更する `ENCRYPT_AND_SIGN`
<a name="ddb-sign-to-encrypt"></a>

既存の `SIGN_ONLY`または `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 属性を に変更するには`ENCRYPT_AND_SIGN`、属性アクションを更新する必要があります。更新をデプロイした後、クライアントは属性に書き込まれた既存の値を検証できるようになり、属性に対して書き込まれた新しい値を暗号化して署名します。

**アノテーション付きデータクラスの使用**  
で属性アクションを定義した場合は`TableSchema`、既存の属性から `@DynamoDBEncryptionSignOnly`または `@DynamoDBEncryptionSignAndIncludeInEncryptionContext`注釈を削除します。

**オブジェクトモデルの使用**  
属性アクションを手動で定義した場合は、オブジェクトモデルの 属性に関連付けられた属性アクションを `SIGN_ONLY`または から `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` `ENCRYPT_AND_SIGN`に更新します。

## 新しい `DO_NOTHING` 属性を追加する
<a name="ddb-add-unauth-attribute"></a>

新しい `DO_NOTHING` 属性を追加する際のエラーのリスクを軽減するには、`DO_NOTHING` 属性に名前を付ける際に個別のプレフィックスを指定し、そのプレフィックスを使用して[許可された署名なし属性](ddb-java-using.md#allowed-unauth)を定義することをお勧めします。

注釈付きデータクラスから既存の `ENCRYPT_AND_SIGN`、`SIGN_ONLY`、または `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 属性を削除し、属性を`DO_NOTHING`属性として再度追加することはできません。まったく新しい `DO_NOTHING` 属性のみを追加できます。

新しい `DO_NOTHING` 属性を追加するために実行するステップは、許可された署名なし属性をリスト内で明示的に定義したか、またはプレフィックスを使用して定義したかによって異なります。

**許可された署名なし属性プレフィックスの使用**  
`TableSchema` を使用して属性アクションを定義した場合は、`@DynamoDBEncryptionDoNothing` アノテーションを使用して新しい `DO_NOTHING` 属性をアノテーション付きデータクラスに追加します。属性アクションを手動で定義した場合は、新しい属性を含むように属性アクションを更新します。必ず `DO_NOTHING` 属性アクションを使用して新しい属性を明示的に設定してください。新しい属性の名前には、同じ個別のプレフィックスを含める必要があります。

**許可された署名なし属性リストの使用**

1. 許可された署名なし属性リストに新しい `DO_NOTHING` 属性を追加し、更新されたリストをデプロイします。

1. **ステップ 1** の変更をデプロイします。

   このデータを読み取る必要があるすべてのホストに変更が反映されるまで、**ステップ 3** に進むことはできません。

1. 新しい `DO_NOTHING` 属性を属性アクションに追加します。

   1. `TableSchema` を使用して属性アクションを定義した場合は、`@DynamoDBEncryptionDoNothing` アノテーションを使用して新しい `DO_NOTHING` 属性をアノテーション付きデータクラスに追加します。

   1. 属性アクションを手動で定義した場合は、新しい属性を含むように属性アクションを更新します。必ず `DO_NOTHING` 属性アクションを使用して新しい属性を明示的に設定してください。

1. **ステップ 3** の変更をデプロイします。

## 既存の `SIGN_ONLY` 属性を `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` に変更する
<a name="ddb-signOnly-to-signInclude"></a>

既存の `SIGN_ONLY` 属性を `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` に変更するには、属性アクションを更新する必要があります。更新をデプロイすると、クライアントは 属性に書き込まれた既存の値を検証でき、 属性に書き込まれた新しい値に署名し続けます。属性に書き込まれた新しい値は、[暗号化コンテキスト](concepts.md#encryption-context)に含まれます。

`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 属性を指定する場合、パーティション属性とソート属性も である必要があります`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`。

**アノテーション付きデータクラスの使用**  
で属性アクションを定義した場合は`TableSchema`、属性に関連付けられた属性アクションを から `@DynamoDBEncryptionSignOnly`に更新します`@DynamoDBEncryptionSignAndIncludeInEncryptionContext`。

**オブジェクトモデルの使用**  
属性アクションを手動で定義した場合は、オブジェクトモデル内で属性に関連付けられた属性アクションを `SIGN_ONLY` から `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` に更新します。

## 既存の `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 属性を `SIGN_ONLY` に変更する
<a name="ddb-signInclude-to-signOnly"></a>

既存の `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 属性を `SIGN_ONLY` に変更するには、属性アクションを更新する必要があります。更新をデプロイすると、クライアントは 属性に書き込まれた既存の値を検証でき、 属性に書き込まれた新しい値に署名し続けます。属性に書き込まれた新しい値は、[暗号化コンテキスト](concepts.md#encryption-context)に含まれません。

既存の`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`属性を に変更する前に`SIGN_ONLY`、更新が[ブランチキー ID サプライヤ](use-hierarchical-keyring.md#branch-key-id-supplier)の機能にどのように影響するかを慎重に検討してください。

**アノテーション付きデータクラスの使用**  
で属性アクションを定義した場合は`TableSchema`、属性に関連付けられた属性アクションを から `@DynamoDBEncryptionSignAndIncludeInEncryptionContext`に更新します`@DynamoDBEncryptionSignOnly`。

**オブジェクトモデルの使用**  
属性アクションを手動で定義した場合は、オブジェクトモデル内で属性に関連付けられた属性アクションを `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` から `SIGN_ONLY` に更新します。

# AWS Database Encryption SDK for DynamoDB で利用可能なプログラミング言語
<a name="ddb-programming-languages"></a>

 AWS Database Encryption SDK for DynamoDB は、次のプログラミング言語で使用できます。言語固有のライブラリはさまざまですが、結果として得られる実装は相互運用ができます。ある言語実装で暗号化し、別の言語実装で復号できます。相互運用性は、言語の制約を受ける可能性があります。その場合の制約については、言語実装に関するトピックで説明します。

**Topics**
+ [Java](ddb-java.md)
+ [.NET](ddb-net.md)
+ [Rust](ddb-rust.md)

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


****  

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

このトピックでは、DynamoDB 用の Java クライアント側の暗号化ライブラリのバージョン 3.x をインストールして使用する方法について説明します。 AWS Database Encryption SDK for DynamoDB を使用したプログラミングの詳細については、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)を参照してください。

**注記**  
次のトピックでは、DynamoDB 用の Java クライアント側の暗号化ライブラリのバージョン 3.x に焦点を当てます。  
クライアント側の暗号化ライブラリの名前が [AWS Database Encryption SDK](DDBEC-rename.md) に変更されました。 AWS Database Encryption SDK は、引き続き[レガシー DynamoDB 暗号化クライアントバージョン](legacy-dynamodb-encryption-client.md)をサポートします。

**Topics**
+ [前提条件](#ddb-java-prerequisites)
+ [インストール](#ddb-java-installation)
+ [Java クライアントの使用](ddb-java-using.md)
+ [Java の例](ddb-java-examples.md)
+ [既存のテーブルにバージョン 3.x を追加する](ddb-java-config-existing-table.md)
+ [バージョン 3.x に移行する](ddb-java-migrate.md)

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

DynamoDB 用の Java クライアント側の暗号化ライブラリのバージョン 3.x をインストールする前に、次の前提条件を満たしていることを確認してください。

**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 2.x**  
 AWS Database Encryption SDK for DynamoDB には、 の [DynamoDB 拡張クライアント](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/dynamodb-enhanced-client.html)モジュールが必要です AWS SDK for Java 2.x。SDK 全体またはこのモジュールだけをインストールできます。  
のバージョンの更新については AWS SDK for Java、[「 のバージョン 1.x から 2.x への移行 AWS SDK for Java](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/migration.html)」を参照してください。  
 AWS SDK for Java は Apache Maven から入手できます。全体の依存関係を宣言することも AWS SDK for Java、`dynamodb-enhanced`モジュールのみの依存関係を宣言することもできます。  

**Apache Maven AWS SDK for Java を使用して をインストールする**
+ 依存関係として [AWS SDK for Java全体をインポートする](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/setup-project-maven.html#build-the-entire-sdk-into-your-project)には、`pom.xml` ファイルでそれを宣言します。
+  AWS SDK for Javaで Amazon DynamoDB モジュールのみの依存関係を作成するには、[特定のモジュールを指定](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/setup-project-maven.html#modules-dependencies)する手順に従います。`groupId` を `software.amazon.awssdk` に、`artifactID` を `dynamodb-enhanced` に設定します。
**注記**  
 AWS KMS キーリングまたは AWS KMS 階層キーリングを使用する場合は、 AWS KMS モジュールの依存関係も作成する必要があります。`groupId` を `software.amazon.awssdk` に、`artifactID` を `kms` に設定します。

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

DynamoDB 用の Java クライアント側の暗号化ライブラリのバージョン 3.x は、次の方法でインストールできます。

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

```
<dependency>
  <groupId>software.amazon.cryptography</groupId>
  <artifactId>aws-database-encryption-sdk-dynamodb</artifactId>
  <version>version-number</version>
</dependency>
```

**Gradle Kotlin の使用**  
Gradle プロジェクトの依存関係セクションに次を追加することで、[Gradle](https://gradle.org/) を使用して Amazon DynamoDB Encryption Client for Java に対する依存関係を宣言できます。  

```
implementation("software.amazon.cryptography:aws-database-encryption-sdk-dynamodb:version-number")
```

**手動**  
DynamoDB 用の Java クライアント側の暗号化ライブラリをインストールするには、[aws-database-encryption-sdk-dynamodb](https://github.com/aws/aws-database-encryption-sdk-dynamodb/) GitHub リポジトリのクローンを作成するか、ダウンロードします。

SDK をインストールしたら、このガイドのコード例と 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)を確認して開始します。

# 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) ディレクトリを参照してください。

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


****  

|  | 
| --- |
| クライアント側の暗号化ライブラリの名前が AWS Database Encryption SDK に変更されました。このデベロッパーガイドでは、引き続き [DynamoDB Encryption Client](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>

次の例は、[AWS KMS キーリング](use-kms-keyring.md)で DynamoDB Enhanced Client と `DynamoDbEncryptionInterceptor` を使用して、DynamoDB API 呼び出しの一部として DynamoDB テーブルの項目を暗号化する方法を示しています。

DynamoDB 拡張クライアントではサポートされている任意の[キーリング](keyrings.md)を使用できますが、可能な限りいずれかの AWS KMS キーリングを使用することをお勧めします。

**注記**  
DynamoDB Enhanced Client は、[検索可能な暗号化](searchable-encryption.md)をサポートしていません。検索可能な暗号化を使用するには、下位レベルの DynamoDB API とともに `DynamoDbEncryptionInterceptor` を使用します。

**完全なコードサンプルを参照してください**: [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 キーリングを作成する**  
次の例では`CreateAwsKmsMrkMultiKeyring`、 を使用して、対称暗号化 KMS AWS KMS キーを使用して キーリングを作成します。`CreateAwsKmsMrkMultiKeyring` メソッドにより、キーリングは、単一リージョンのキーとマルチリージョンのキーの両方を確実に正しく処理します。  

```
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 テーブル名を論理テーブル名として指定することを強くお勧めします。詳細については、「[AWS Database Encryption SDK for DynamoDB の暗号化設定](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** の `tableConfigs` を使用して新しい `DynamoDbEncryptionInterceptor` を作成します。  

```
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 Enhanced Client を作成し、テーブルを作成する**  
次の例では、**ステップ 6** で作成した AWS SDK DynamoDB クライアントを使用して DynamoDB Enhanced Client を作成し、アノテーション付きデータクラスを使用してテーブルを作成します。  

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

**ステップ 8: テーブル項目を暗号化して署名する**  
次の例では、DynamoDB Enhanced Client を使用して項目を 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>

次の例は、[AWS KMS キーリング](use-kms-keyring.md)とともに下位レベルの DynamoDB API を使用し、DynamoDB `PutItem` リクエストを使用してクライアント側で項目を自動的に暗号化して署名する方法を示しています。

サポートされている任意の[キーリング](keyrings.md)を使用できますが、可能な限りいずれかの AWS KMS キーリングを使用することをお勧めします。

**完全なコードサンプルを参照してください**: [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 キーリングを作成する**  
次の例では`CreateAwsKmsMrkMultiKeyring`、 を使用して、対称暗号化 KMS AWS KMS キーを使用して キーリングを作成します。`CreateAwsKmsMrkMultiKeyring` メソッドにより、キーリングは、単一リージョンのキーとマルチリージョンのキーの両方を確実に正しく処理します。  

```
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 テーブル名を論理テーブル名として指定することを強くお勧めします。詳細については、「[AWS Database Encryption SDK for DynamoDB の暗号化設定](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` を作成する**  
次の例では、**ステップ 4** の `tableConfigs` を使用して `DynamoDbEncryptionInterceptor` を作成します。  

```
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 キーリング](use-kms-keyring.md)とともに使用して、テーブル項目を直接暗号化して署名する方法を示しています。`DynamoDbItemEncryptor` は項目を DynamoDB テーブルに配置しません。

DynamoDB 拡張クライアントではサポートされている任意の[キーリング](keyrings.md)を使用できますが、可能な限りいずれかの AWS KMS キーリングを使用することをお勧めします。

**注記**  
下位レベルの `DynamoDbItemEncryptor` は、[検索可能な暗号化](searchable-encryption.md)をサポートしていません。検索可能な暗号化を使用するには、下位レベルの DynamoDB API とともに `DynamoDbEncryptionInterceptor` を使用します。

**完全なコードサンプルを参照してください**: [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 キーリングを作成する**  
次の例では`CreateAwsKmsMrkMultiKeyring`、 を使用して、対称暗号化 KMS AWS KMS キーを使用して キーリングを作成します。`CreateAwsKmsMrkMultiKeyring` メソッドにより、キーリングは、単一リージョンのキーとマルチリージョンのキーの両方を確実に正しく処理します。  

```
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 テーブル名を論理テーブル名として指定することを強くお勧めします。詳細については、「[AWS Database Encryption SDK for DynamoDB の暗号化設定](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` を作成する**  
次の例では、**ステップ 4** の `config` を使用して新しい `DynamoDbItemEncryptor` を作成します。  

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

# AWS Database Encryption SDK for DynamoDB を使用するように既存の DynamoDB テーブルを設定する
<a name="ddb-java-config-existing-table"></a>


****  

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

DynamoDB 用の Java クライアント側の暗号化ライブラリのバージョン 3.x を使用すると、既存の Amazon DynamoDB テーブルをクライアント側の暗号化用に設定できます。このトピックでは、データが入力されている既存の DynamoDB テーブルにバージョン 3.x を追加するために必要な 3 つのステップについてのガイダンスを提供します。

**前提条件**  
DynamoDB 用の Java クライアント側の暗号化ライブラリのバージョン 3.x では、 AWS SDK for Java 2.x で提供される [DynamoDB Enhanced Client](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/dynamodb-enhanced-client.html) が必要です。[DynamoDBMapper](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBMapper.Methods.html) を引き続き使用する場合は、DynamoDB 拡張クライアント AWS SDK for Java 2.x を使用するには に移行する必要があります。

 [AWS SDK for Javaのバージョン 1.x から 2.x に移行](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/migration.html)する手順に従います。

その後、[DynamoDB Enhanced Client API の使用を開始](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/ddb-en-client-getting-started.html)するための手順に従います。

DynamoDB 用の Java クライアント側の暗号化ライブラリを使用するようにテーブルを設定する前に、[アノテーション付きデータクラスを使用して](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/ddb-en-client-gs-tableschema.html#ddb-en-client-gs-tableschema-anno-bean) `TableSchema` を生成し、[拡張クライアントを作成](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>

Database Encryption SDK AWS クライアントが暗号化された項目を読み書きできるように準備するには、次の手順を実行します。次の変更をデプロイした後も、クライアントは引き続きプレーンテキスト項目の読み取りと書き込みを行います。テーブルに書き込まれる新しい項目の暗号化や署名は行いませんが、暗号化された項目が表示されるとすぐに復号できます。これらの変更により、クライアントが[新しい項目の暗号化](#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) を参照してください。  
デフォルトでは、プライマリキー属性は署名されてはいるが、暗号化されておらず (`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. [キーリング](keyrings.md)を作成します。**  
次の例では [AWS KMS キーリング](use-kms-keyring.md)を作成します。 AWS KMS キーリングは、対称暗号化または非対称 RSA AWS KMS keys を使用してデータキーを生成、暗号化、復号します。  
この例では、`CreateMrkMultiKeyring` を使用して、対称暗号化 KMS キーで AWS KMS キーリングを作成します。`CreateAwsKmsMrkMultiKeyring` メソッドにより、キーリングは、単一リージョンのキーとマルチリージョンのキーの両方を確実に正しく処理します。  

```
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 テーブル名を論理テーブル名として指定することを強くお勧めします。詳細については、「[AWS Database Encryption SDK for DynamoDB の暗号化設定](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` の作成**  
次の例では、**ステップ 3** の `tableConfigs` を使用して `DynamoDbEncryptionInterceptor` を作成します。  

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

# DynamoDB 用の Java クライアント側の暗号化ライブラリのバージョン 3.x に移行する
<a name="ddb-java-migrate"></a>


****  

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

DynamoDB 用の Java クライアント側の暗号化ライブラリのバージョン 3.x は、2.x コードベースを大幅に書き直したものです。これには、新しい構造化データ形式、マルチテナンシーのサポートの改善、シームレスなスキーマの変更、検索可能な暗号化のサポートなど、多くの更新が含まれています。このトピックでは、コードをバージョン 3.x に移行する方法について説明します。

## バージョン 1.x から 2.x への移行
<a name="ddb-java-v1-to-v2"></a>

バージョン 3.x に移行する前に、バージョン 2.x に移行してください。バージョン 2.x では、最新プロバイダーの符号が `MostRecentProvider` から `CachingMostRecentProvider` に変更されました。現在、符号が `MostRecentProvider` である DynamoDB 用の Java クライアント側の暗号化ライブラリのバージョン 1.x を使用している場合は、コード内の符号名を `CachingMostRecentProvider` に更新する必要があります。詳細については、「[最新のプロバイダーに更新する](most-recent-provider.md#mrp-versions)」を参照してください。

## バージョン 2.x から 3.x への移行
<a name="ddb-java-v2-to-v3"></a>

次の手順では、DynamoDB 用の Java クライアント側の暗号化ライブラリのコードをバージョン 2.x からバージョン 3.x に移行する方法について説明します。

### ステップ 1. 新しい形式で項目を読み取る準備をする
<a name="ddb-java-migrate-step1"></a>

Database Encryption SDK AWS クライアントが新しい形式の項目を読み取る準備をするには、次の手順を実行します。次の変更をデプロイした後、クライアントは引き続きバージョン 2.x と同じように動作します。クライアントは引き続きバージョン 2.x 形式で項目の読み取りと書き込みを行いますが、これらの変更により、クライアントが新しい形式で項目を読み取る準備が整います。

**をバージョン 2.x AWS SDK for Java に更新する**  
DynamoDB 用の Java クライアント側の暗号化ライブラリのバージョン 3.x では、[DynamoDB Enhanced Client](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/dynamodb-enhanced-client.html) が必要です。DynamoDB Enhanced Client は、以前のバージョンで使用されていた [DynamoDBMapper](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBMapper.Methods.html) を置き換えます。拡張クライアントを使用するには、 AWS SDK for Java 2.xを使用する必要があります。  
[AWS SDK for Javaのバージョン 1.x から 2.x に移行](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/migration.html)する手順に従います。  
必要な AWS SDK for Java 2.x モジュールの詳細については、「」を参照してください[前提条件](ddb-java.md#ddb-java-prerequisites)。

**従来のバージョンによって暗号化された項目を読み取るようにクライアントを設定する**  
次の手順では、以下のコード例で示されているステップの概要を説明します。  

1. キーリングを作成します。

   キーリングと[暗号マテリアルマネージャー](concepts.md#crypt-materials-manager)は、DynamoDB 用の Java クライアント側の暗号化ライブラリの以前のバージョンで使用されていた暗号マテリアルプロバイダーを置き換えます。
**重要**  
キーリングの作成時に指定するラッピングキーは、バージョン 2.x で暗号マテリアルプロバイダーで使用したのと同じラッピングキーである必要があります。

1. アノテーション付きクラスに基づいてテーブルスキーマを作成します。

   このステップでは、新しい形式で項目の書き込みを開始するときに使用される属性アクションを定義します。

   新しい DynamoDB Enhanced Client の使用に関するガイダンスについては、「AWS SDK for Java デベロッパーガイド」の「[`TableSchema` を生成する](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/ddb-en-client-gs-tableschema.html)」を参照してください。

   次の例では、新しい属性アクションのアノテーションを使用して、アノテーション付きクラスをバージョン 2.x から更新したことを前提としています。属性アクションにアノテーションを付ける方法のガイダンスについては、「[アノテーション付きデータクラスを使用する](ddb-java-using.md#ddb-attribute-actions-annotated-data-class)」を参照してください。
**注記**  
`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)」を参照してください。

1. どの[属性を署名から除外](ddb-java-using.md#allowed-unauth)するかを定義します。

1. バージョン 2.x のモデル化されたクラスで設定された属性アクションの明示的なマッピングを設定します。

   このステップでは、古い形式で項目を書き込むために使用される属性アクションを定義します。

1. DynamoDB 用の Java クライアント側の暗号化ライブラリのバージョン 2.x で使用した `DynamoDBEncryptor` を設定します。

1. 従来の動作を設定します。

1. `DynamoDbEncryptionInterceptor` を作成します。

1. 新しい AWS SDK DynamoDB クライアントを作成します。

1. `DynamoDBEnhancedClient` を作成し、モデル化されたクラスを含むテーブルを作成します。

   DynamoDB Enhanced Client の詳細については、「[拡張クライアントを作成する](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)」を参照してください。

```
public class MigrationExampleStep1 {

    public static void MigrationStep1(String kmsKeyId, String ddbTableName, int sortReadValue) {
        // 1. Create a Keyring.
        //    This example creates an AWS KMS Keyring that specifies the 
        //    same kmsKeyId previously used in the version 2.x configuration.
        //    It uses the 'CreateMrkMultiKeyring' method to create the 
        //    keyring, so that the keyring can correctly handle both single
        //    region and Multi-Region KMS Keys.
        //    Note that this example uses the AWS SDK for Java v2 KMS client.
        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. Create a Table Schema over your annotated class.
        //    For guidance on using the new attribute actions 
        //    annotations, see SimpleClass.java in the 
        //    aws-database-encryption-sdk-dynamodb GitHub repository. 
        //    All primary key attributes must be signed but not encrypted 
        //    and by default all non-primary key attributes 
        //    are encrypted and signed (ENCRYPT_AND_SIGN).
        //    If you want a particular non-primary key attribute to be signed but
        //    not encrypted, use the 'DynamoDbEncryptionSignOnly' annotation.
        //    If you want a particular attribute to be neither signed nor encrypted
        //    (DO_NOTHING), use the 'DynamoDbEncryptionDoNothing' annotation.
        final TableSchema<SimpleClass> schemaOnEncrypt = TableSchema.fromBean(SimpleClass.class);

        // 3. Define which attributes the client should expect to be excluded 
        //    from the signature when reading items.
        //    This value represents all unsigned attributes across the entire 
        //    dataset.
        final List<String> allowedUnsignedAttributes = Arrays.asList("attribute3");

        // 4. Configure an explicit map of the attribute actions configured 
        //    in your version 2.x modeled class.
        final Map<String, CryptoAction> legacyActions = new HashMap<>();
        legacyActions.put("partition_key", CryptoAction.SIGN_ONLY);
        legacyActions.put("sort_key", CryptoAction.SIGN_ONLY);
        legacyActions.put("attribute1", CryptoAction.ENCRYPT_AND_SIGN);
        legacyActions.put("attribute2", CryptoAction.SIGN_ONLY);
        legacyActions.put("attribute3", CryptoAction.DO_NOTHING);

        // 5. Configure the DynamoDBEncryptor that you used in version 2.x.
        final AWSKMS kmsClient = AWSKMSClientBuilder.defaultClient();
        final DirectKmsMaterialProvider cmp = new DirectKmsMaterialProvider(kmsClient, kmsKeyId);
        final DynamoDBEncryptor oldEncryptor = DynamoDBEncryptor.getInstance(cmp);

        // 6. Configure the legacy behavior.
        //    Input the DynamoDBEncryptor and attribute actions created in 
        //    the previous steps. For Legacy Policy, use 
        //    'FORCE_LEGACY_ENCRYPT_ALLOW_LEGACY_DECRYPT'. This policy continues to read 
        //    and write items using the old format, but will be able to read
        //    items written in the new format as soon as they appear.
        final LegacyOverride legacyOverride = LegacyOverride
                .builder()
                .encryptor(oldEncryptor)
                .policy(LegacyPolicy.FORCE_LEGACY_ENCRYPT_ALLOW_LEGACY_DECRYPT)
                .attributeActionsOnEncrypt(legacyActions)
                .build();

        // 7. Create a DynamoDbEncryptionInterceptor with the above configuration.
        final Map<String, DynamoDbEnhancedTableEncryptionConfig> tableConfigs = new HashMap<>();
        tableConfigs.put(ddbTableName,
                DynamoDbEnhancedTableEncryptionConfig.builder()
                        .logicalTableName(ddbTableName)
                        .keyring(kmsKeyring)
                        .allowedUnsignedAttributes(allowedUnsignedAttributes)
                        .schemaOnEncrypt(tableSchema)
                        .legacyOverride(legacyOverride)
                        .build());
        final DynamoDbEncryptionInterceptor interceptor =
                DynamoDbEnhancedClientEncryption.CreateDynamoDbEncryptionInterceptor(
                        CreateDynamoDbEncryptionInterceptorInput.builder()
                                .tableEncryptionConfigs(tableConfigs)
                                .build()
                );

        // 8. Create a new AWS SDK DynamoDb client using the 
        //    interceptor from Step 7.
        final DynamoDbClient ddb = DynamoDbClient.builder()
                .overrideConfiguration(
                        ClientOverrideConfiguration.builder()
                                .addExecutionInterceptor(interceptor)
                                .build())
                .build();

        // 9. Create the DynamoDbEnhancedClient using the AWS SDK DynamoDb client 
        //    created in Step 8, and create a table with your modeled class.
        final DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder()
                .dynamoDbClient(ddb)
                .build();
        final DynamoDbTable<SimpleClass> table = enhancedClient.table(ddbTableName, tableSchema);
    }
}
```

### ステップ 2. 新しい形式で項目を書き込む
<a name="ddb-java-migrate-step2"></a>

ステップ 1 からすべてのリーダーに変更をデプロイしたら、次のステップを実行して、新しい形式で項目を書き込むように AWS Database Encryption SDK クライアントを設定します。次の変更をデプロイした後、クライアントは引き続き古い形式で項目を読み取り、新しい形式で項目の書き込みと読み取りを開始します。

次の手順では、以下のコード例で示されているステップの概要を説明します。

1. [**ステップ 1**](#ddb-java-migrate-step1) と同様に、キーリング、テーブルスキーマ、従来の属性アクション、`allowedUnsignedAttributes`、および `DynamoDBEncryptor` の設定を続行します。

1. 新しい形式を使用して新しい項目のみを書き込むように、従来の動作を更新します。

1. `DynamoDbEncryptionInterceptor ` を作成する

1. 新しい AWS SDK DynamoDB クライアントを作成します。

1. `DynamoDBEnhancedClient` を作成し、モデル化されたクラスを含むテーブルを作成します。

   DynamoDB Enhanced Client の詳細については、「[拡張クライアントを作成する](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)」を参照してください。

```
public class MigrationExampleStep2 {

    public static void MigrationStep2(String kmsKeyId, String ddbTableName, int sortReadValue) {
        // 1. Continue to configure your keyring, table schema, legacy 
        //    attribute actions, allowedUnsignedAttributes, and 
        //    DynamoDBEncryptor as you did in Step 1.
        final MaterialProviders matProv = MaterialProviders.builder()
                .MaterialProvidersConfig(MaterialProvidersConfig.builder().build())
                .build();
        final CreateAwsKmsMrkMultiKeyringInput keyringInput = CreateAwsKmsMrkMultiKeyringInput.builder()
                .generator(kmsKeyId)
                .build();
        final IKeyring kmsKeyring = matProv.CreateAwsKmsMrkMultiKeyring(keyringInput);

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

        final List<String> allowedUnsignedAttributes = Arrays.asList("attribute3");

        final Map<String, CryptoAction> legacyActions = new HashMap<>();
        legacyActions.put("partition_key", CryptoAction.SIGN_ONLY);
        legacyActions.put("sort_key", CryptoAction.SIGN_ONLY);
        legacyActions.put("attribute1", CryptoAction.ENCRYPT_AND_SIGN);
        legacyActions.put("attribute2", CryptoAction.SIGN_ONLY);
        legacyActions.put("attribute3", CryptoAction.DO_NOTHING);

        final AWSKMS kmsClient = AWSKMSClientBuilder.defaultClient();
        final DirectKmsMaterialProvider cmp = new DirectKmsMaterialProvider(kmsClient, kmsKeyId);
        final DynamoDBEncryptor oldEncryptor = DynamoDBEncryptor.getInstance(cmp);

        // 2. Update your legacy behavior to only write new items using the new
        //    format. 
        //    For Legacy Policy, use 'FORBID_LEGACY_ENCRYPT_ALLOW_LEGACY_DECRYPT'. This policy
        //    continues to read items in both formats, but will only write items
        //    using the new format.
        final LegacyOverride legacyOverride = LegacyOverride
                .builder()
                .encryptor(oldEncryptor)
                .policy(LegacyPolicy.FORBID_LEGACY_ENCRYPT_ALLOW_LEGACY_DECRYPT)
                .attributeActionsOnEncrypt(legacyActions)
                .build();

        // 3. Create a DynamoDbEncryptionInterceptor with the above configuration.
        final Map<String, DynamoDbEnhancedTableEncryptionConfig> tableConfigs = new HashMap<>();
        tableConfigs.put(ddbTableName,
                DynamoDbEnhancedTableEncryptionConfig.builder()
                        .logicalTableName(ddbTableName)
                        .keyring(kmsKeyring)
                        .allowedUnsignedAttributes(allowedUnsignedAttributes)
                        .schemaOnEncrypt(tableSchema)
                        .legacyOverride(legacyOverride)
                        .build());
        final DynamoDbEncryptionInterceptor interceptor =
                DynamoDbEnhancedClientEncryption.CreateDynamoDbEncryptionInterceptor(
                        CreateDynamoDbEncryptionInterceptorInput.builder()
                                .tableEncryptionConfigs(tableConfigs)
                                .build()
                );

        // 4. Create a new AWS SDK DynamoDb client using the 
        //    interceptor from Step 3.
        final DynamoDbClient ddb = DynamoDbClient.builder()
                .overrideConfiguration(
                        ClientOverrideConfiguration.builder()
                                .addExecutionInterceptor(interceptor)
                                .build())
                .build();

        // 5. Create the DynamoDbEnhancedClient using the AWS SDK DynamoDb Client created
        //    in Step 4, and create a table with your modeled class.
        final DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder()
                .dynamoDbClient(ddb)
                .build();
        final DynamoDbTable<SimpleClass> table = enhancedClient.table(ddbTableName, tableSchema);
    }
}
```

ステップ 2 の変更をデプロイした後、[ステップ 3](#ddb-java-migrate-step3) に進む前に、テーブル内のすべての古い項目を新しい形式で再暗号化する必要があります。既存の項目を迅速に暗号化するために実行できる単一のメトリクスやクエリはありません。システムにとって最も合理的なプロセスを使用してください。例えば、定義した新しい属性アクションと暗号化設定を使用して、時間をかけてテーブルをスキャンし、項目を書き換える非同期プロセスを使用できます。

### ステップ 3. 新しい形式でのみ項目を読み書きする
<a name="ddb-java-migrate-step3"></a>

テーブル内のすべての項目を新しい形式で再暗号化した後、設定から従来の動作を削除できます。新しい形式でのみ項目を読み書きするようにクライアントを設定するには、次のステップを実行します。

次の手順では、以下のコード例で示されているステップの概要を説明します。

1. [**ステップ 1**](#ddb-java-migrate-step1) と同様に、キーリング、テーブルスキーマ、`allowedUnsignedAttributes` の設定を続行します。従来の属性アクションと `DynamoDBEncryptor` を設定から削除します。

1. `DynamoDbEncryptionInterceptor` を作成します。

1. 新しい AWS SDK DynamoDB クライアントを作成します。

1. `DynamoDBEnhancedClient` を作成し、モデル化されたクラスを含むテーブルを作成します。

   DynamoDB Enhanced Client の詳細については、「[拡張クライアントを作成する](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)」を参照してください。

```
public class MigrationExampleStep3 {

    public static void MigrationStep3(String kmsKeyId, String ddbTableName, int sortReadValue) {
        // 1. Continue to configure your keyring, table schema,
        //    and allowedUnsignedAttributes as you did in Step 1.
        //    Do not include the configurations for the DynamoDBEncryptor or 
        //    the legacy attribute actions.
        final MaterialProviders matProv = MaterialProviders.builder()
                .MaterialProvidersConfig(MaterialProvidersConfig.builder().build())
                .build();
        final CreateAwsKmsMrkMultiKeyringInput keyringInput = CreateAwsKmsMrkMultiKeyringInput.builder()
                .generator(kmsKeyId)
                .build();
        final IKeyring kmsKeyring = matProv.CreateAwsKmsMrkMultiKeyring(keyringInput);

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

        final List<String> allowedUnsignedAttributes = Arrays.asList("attribute3");


        // 3. Create a DynamoDbEncryptionInterceptor with the above configuration.
        //    Do not configure any legacy behavior.
        final Map<String, DynamoDbEnhancedTableEncryptionConfig> tableConfigs = new HashMap<>();
        tableConfigs.put(ddbTableName,
                DynamoDbEnhancedTableEncryptionConfig.builder()
                        .logicalTableName(ddbTableName)
                        .keyring(kmsKeyring)
                        .allowedUnsignedAttributes(allowedUnsignedAttributes)
                        .schemaOnEncrypt(tableSchema)
                        .build());
        final DynamoDbEncryptionInterceptor interceptor =
                DynamoDbEnhancedClientEncryption.CreateDynamoDbEncryptionInterceptor(
                        CreateDynamoDbEncryptionInterceptorInput.builder()
                                .tableEncryptionConfigs(tableConfigs)
                                .build()
                );

        // 4. Create a new AWS SDK DynamoDb client using the 
        //    interceptor from Step 3.
        final DynamoDbClient ddb = DynamoDbClient.builder()
                .overrideConfiguration(
                        ClientOverrideConfiguration.builder()
                                .addExecutionInterceptor(interceptor)
                                .build())
                .build();

        // 5. Create the DynamoDbEnhancedClient using the AWS SDK Client 
        //    created in Step 4, and create a table with your modeled class.
        final DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder()
                .dynamoDbClient(ddb)
                .build();
        final DynamoDbTable<SimpleClass> table = enhancedClient.table(ddbTableName, tableSchema);
    }
}
```

# .NET
<a name="ddb-net"></a>

このトピックでは、DynamoDB 用の .NET クライアント側の暗号化ライブラリのバージョン 3.*x* をインストールして使用する方法について説明します。 AWS Database Encryption SDK for DynamoDB を使用したプログラミングの詳細については、GitHub の aws-database-encryption-sdk-dynamodb リポジトリの [.NET の例](https://github.com/aws/aws-database-encryption-sdk-dynamodb/tree/main/Examples/runtimes/net/src/)を参照してください。

DynamoDB 用の .NET クライアント側の暗号化ライブラリは、C\$1 やその他の .NET プログラミング言語でアプリケーションを記述している開発者を対象としています。Windows、macOS、Linux でサポートされています。

 AWS Database Encryption SDK for DynamoDB のすべての[プログラミング言語](ddb-programming-languages.md)実装は相互運用可能です。ただし、 SDK for .NET では、リストデータ型またはマップデータ型の空の値はサポートされていません。つまり、DynamoDB 用の Java クライアント側の暗号化ライブラリを使用して、リストまたはマップデータ型の空の値を含む項目を書き込む場合、DynamoDB 用の .NET クライアント側の暗号化ライブラリを使用してその項目を復号化して読み取ることはできません。

**Topics**
+ [インストール](#ddb-net-install)
+ [デバッグ](#ddb-net-debugging)
+ [.NET クライアントの使用](ddb-net-using.md)
+ [.NET の例](ddb-net-examples.md)
+ [既存のテーブルにバージョン 3.x を追加する](ddb-net-config-existing-table.md)

## DynamoDB 用の .NET クライアント側の暗号化ライブラリのインストール
<a name="ddb-net-install"></a>

DynamoDB 用の .NET クライアント側の暗号化ライブラリは、NuGet の [AWS.Cryptography.DbEncryptionSDK.DynamoDb](https://www.nuget.org/packages/AWS.Cryptography.DbEncryptionSDK.DynamoDb/) パッケージとして利用できます。ライブラリのインストールと構築の詳細については、aws-database-encryption-sdk-dynamodb リポジトリの [.NET README.md](https://github.com/aws/aws-database-encryption-sdk-dynamodb/blob/main/DynamoDbEncryption/runtimes/net/README.md) ファイルを参照してください。DynamoDB 用の .NET クライアント側の暗号化ライブラリには、 AWS Key Management Service (AWS KMS) キーを使用していない場合 SDK for .NET でも が必要です。は NuGet SDK for .NET パッケージと共にインストールされます。

DynamoDB 用の .NET クライアント側の暗号化ライブラリのバージョン 3.*x* は、.NET 6.0 および .NET Framework net48 以降をサポートしています。

## .NET を使用したデバッグ
<a name="ddb-net-debugging"></a>

DynamoDB 用の .NET クライアント側の暗号化ライブラリはログを生成しません。DynamoDB 用の .NET クライアント側の暗号化ライブラリの例外は例外メッセージを生成しますが、スタックトレースは生成されません。

デバッグしやすいように、 SDK for .NETへのログ記録を必ず有効にしてください。からのログとエラーメッセージ SDK for .NET は、 で発生するエラーを、DynamoDB 用の .NET クライアント側の暗号化ライブラリのエラー SDK for .NET と区別するのに役立ちます。 SDK for .NET ログ記録については、「 *AWS SDK for .NET デベロッパーガイド*」の[AWSLogging](https://docs.aws.amazon.com/sdk-for-net/latest/developer-guide/net-dg-config-other.html#config-setting-awslogging)」を参照してください。(このトピックを確認するには、**[.NET Framework コンテンツを開く]** セクションを展開してください)。

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

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

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

**Topics**
+ [項目エンクリプタ](#ddb-net-item-encryptors)
+ [属性アクション](#ddb-net-attribute-actions)
+ [暗号化設定](#ddb-net-config-encrypt)
+ [項目の更新](#ddb-net-update-items)

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

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

**DynamoDB API 用の低レベル AWS データベース暗号化 SDK**  
[テーブル暗号化設定](#ddb-net-config-encrypt)を使用して、DynamoDB `PutItem`リクエストでクライアント側で項目を自動的に暗号化して署名する DynamoDB クライアントを構築できます。このクライアントを直接使用するか、[ドキュメントモデル](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/dynamodb-intro.html#dynamodb-intro-apis-document)または[オブジェクト永続性モデル](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/dynamodb-intro.html#dynamodb-intro-apis-object-persistence)を構築できます。  
[検索可能な](searchable-encryption.md)暗号化を使用するには、低レベルの AWS Database Encryption SDK for DynamoDB API を使用する必要があります。

**下位レベルの `DynamoDbItemEncryptor`**  
下位レベルの `DynamoDbItemEncryptor` は、DynamoDB を呼び出すことなく、テーブル項目を直接暗号化して署名するか、または復号して検証します。DynamoDB の `PutItem` または `GetItem` リクエストは実行しません。例えば、下位レベルの `DynamoDbItemEncryptor` を使用して、既に取得した DynamoDB 項目を直接復号して検証できます。低レベルの を使用する場合は`DynamoDbItemEncryptor`、 が DynamoDB との通信 SDK for .NET に提供する[低レベルのプログラミングモデル](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/dynamodb-intro.html#dynamodb-intro-apis-low-level)を使用することをお勧めします。  
下位レベルの `DynamoDbItemEncryptor` は、[検索可能な暗号化](searchable-encryption.md)をサポートしていません。

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

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

.NET クライアントで属性アクションを指定するには、オブジェクトモデルを使用して属性アクションを手動で定義します。名前と値のペアが属性名と指定されたアクションを表す`Dictionary`オブジェクトを作成して、属性アクションを指定します。

属性を暗号化して署名するように `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`。

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

次のオブジェクトモデルは`ENCRYPT_AND_SIGN`、.NET クライアントで `SIGN_ONLY`、`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`、、および `DO_NOTHING` 属性アクションを指定する方法を示しています。この例では、プレフィックス`:`「」を使用して`DO_NOTHING`属性を識別します。

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

```
var attributeActionsOnEncrypt = new Dictionary<string, CryptoAction>
{
    ["partition_key"] = CryptoAction.SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT, // The partition attribute must be signed
    ["sort_key"] = CryptoAction.SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT, // The sort attribute must be signed
    ["attribute1"] = CryptoAction.ENCRYPT_AND_SIGN,
    ["attribute2"] = CryptoAction.SIGN_ONLY,
    ["attribute3"] = CryptoAction.SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT,
    [":attribute4"] = CryptoAction.DO_NOTHING
};
```

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

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

次のスニペットは、低レベルの AWS Database Encryption SDK for DynamoDB API と、個別のプレフィックスで定義された許可された署名なし属性を使用して、DynamoDB テーブル暗号化設定を定義します。

```
Dictionary<String, DynamoDbTableEncryptionConfig> tableConfigs =
    new Dictionary<String, DynamoDbTableEncryptionConfig>();
DynamoDbTableEncryptionConfig config = new DynamoDbTableEncryptionConfig
{
    LogicalTableName = ddbTableName,
    PartitionKeyName = "partition_key",
    SortKeyName = "sort_key",
    AttributeActionsOnEncrypt = attributeActionsOnEncrypt,
    Keyring = kmsKeyring,
    AllowedUnsignedAttributePrefix = unsignAttrPrefix,
    // Optional: SearchConfig only required if you use beacons
    Search = new SearchConfig
    {
        WriteVersion = 1, // MUST be 1
        Versions = beaconVersions
    }    
};
tableConfigs.Add(ddbTableName, config);
```

**論理テーブル名**  
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-net-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) を使用して、項目を更新した後、保存する際にすべての属性をクリアして置き換えることもできます。

# .NET の例
<a name="ddb-net-examples"></a>

次の例は、DynamoDB 用の .NET クライアント側の暗号化ライブラリを使用して、アプリケーション内のテーブル項目を保護する方法を示しています。その他の例を見つける (および独自の例を提供する) には、GitHub の aws-database-encryption-sdk-dynamodb リポジトリにある [.NET の例](https://github.com/aws/aws-database-encryption-sdk-dynamodb//tree/main/Examples/runtimes/net/src)を参照してください。

次の例は、入力されていない新しい Amazon DynamoDB テーブルで DynamoDB 用の .NET クライアント側の暗号化ライブラリを設定する方法を示しています。既存の Amazon DynamoDB テーブルをクライアント側の暗号化のために設定する場合は、「[既存のテーブルにバージョン 3.x を追加する](ddb-net-config-existing-table.md)」を参照してください。

**Topics**
+ [低レベルの AWS Database Encryption SDK for DynamoDB API の使用](#ddb-net-lowlevel-API-example)
+ [下位レベルの使用 `DynamoDbItemEncryptor`](#ddb-net-itemencryptor)

## 低レベルの AWS Database Encryption SDK for DynamoDB API の使用
<a name="ddb-net-lowlevel-API-example"></a>

次の例は、 [AWS KMS キーリング](use-kms-keyring.md)で低レベルの AWS Database Encryption SDK for DynamoDB API を使用して、DynamoDB `PutItem`リクエストでクライアント側で項目を自動的に暗号化して署名する方法を示しています。

サポートされている任意の[キーリング](keyrings.md)を使用できますが、可能な限りいずれかの AWS KMS キーリングを使用することをお勧めします。

**完全なコードサンプルを参照**: [BasicPutGetExample.cs](https://github.com/aws/aws-database-encryption-sdk-dynamodb/tree/main/Examples/runtimes/net/src/BasicPutGetExample.cs)

**ステップ 1: AWS KMS キーリングを作成する**  
次の例では、 `CreateAwsKmsMrkMultiKeyring`を使用して対称暗号化 KMS AWS KMS キーを持つ キーリングを作成します。`CreateAwsKmsMrkMultiKeyring` メソッドにより、キーリングは、単一リージョンのキーとマルチリージョンのキーの両方を確実に正しく処理します。  

```
var matProv = new MaterialProviders(new MaterialProvidersConfig());
var keyringInput = new CreateAwsKmsMrkMultiKeyringInput { Generator = kmsKeyId };
var 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`。

```
var attributeActionsOnEncrypt = new Dictionary<string, CryptoAction>
{
    ["partition_key"] = CryptoAction.SIGN_ONLY, // The partition attribute must be SIGN_ONLY
    ["sort_key"] = CryptoAction.SIGN_ONLY, // The sort attribute must be SIGN_ONLY
    ["attribute1"] = CryptoAction.ENCRYPT_AND_SIGN,
    ["attribute2"] = CryptoAction.SIGN_ONLY,
    [":attribute3"] = CryptoAction.DO_NOTHING
};
```

**ステップ 3: 署名から除外する属性を定義する**  
次の例では、すべての `DO_NOTHING` 属性が個別のプレフィックス「`:`」を共有し、そのプレフィックスを使用して、許可される署名なし属性を定義すると想定しています。クライアントは、「`:`」というプレフィックスが付いた属性名は署名から除外されると想定します。詳細については、「[Allowed unsigned attributes](ddb-net-using.md#net-allowed-unauth)」を参照してください。  

```
const String unsignAttrPrefix = ":";
```

**ステップ 4: DynamoDB テーブルの暗号化設定を定義する**  
次の例では、この DynamoDB テーブルの暗号化設定を表す `tableConfigs` マップを定義します。  
この例では、DynamoDB テーブル名を[論理テーブル名](ddb-net-using.md#net-logical-table-name)として指定します。最初に暗号化設定を定義する際に、DynamoDB テーブル名を論理テーブル名として指定することを強くお勧めします。詳細については、「[AWS Database Encryption SDK for DynamoDB の暗号化設定](ddb-net-using.md#ddb-net-config-encrypt)」を参照してください。  
[検索可能な暗号化](searchable-encryption.md)または[署名付きビーコン](configure.md#signed-beacons)を使用するには、暗号化設定に [`SearchConfig`](ddb-java-using.md#ddb-search-config) も含める必要があります。

```
Dictionary<String, DynamoDbTableEncryptionConfig> tableConfigs =
    new Dictionary<String, DynamoDbTableEncryptionConfig>();
DynamoDbTableEncryptionConfig config = new DynamoDbTableEncryptionConfig
{
    LogicalTableName = ddbTableName,
    PartitionKeyName = "partition_key",
    SortKeyName = "sort_key",
    AttributeActionsOnEncrypt = attributeActionsOnEncrypt,
    Keyring = kmsKeyring,
    AllowedUnsignedAttributePrefix = unsignAttrPrefix
};
tableConfigs.Add(ddbTableName, config);
```

**ステップ 5: 新しい AWS SDK DynamoDB クライアントを作成する**  
次の例では、**ステップ 4** `TableEncryptionConfigs`の を使用して新しい AWS SDK DynamoDB クライアントを作成します。  

```
var ddb = new Client.DynamoDbClient(
    new DynamoDbTablesEncryptionConfig { TableEncryptionConfigs = tableConfigs });
```

**ステップ 6: DynamoDB テーブル項目を暗号化して署名する**  
次の例では、サンプルテーブル項目を表す`item`ディクショナリを定義し、その項目を DynamoDB テーブルに配置します。項目は、DynamoDB に送信される前に、クライアント側で暗号化および署名されます。  

```
var item = new Dictionary<String, AttributeValue>
{
    ["partition_key"] = new AttributeValue("BasicPutGetExample"),
    ["sort_key"] = new AttributeValue { N = "0" },
    ["attribute1"] = new AttributeValue("encrypt and sign me!"),
    ["attribute2"] = new AttributeValue("sign me!"),
    [":attribute3"] = new AttributeValue("ignore me!")
};

PutItemRequest putRequest = new PutItemRequest
{
    TableName = ddbTableName,
    Item = item
};

PutItemResponse putResponse = await ddb.PutItemAsync(putRequest);
```

## 下位レベルの使用 `DynamoDbItemEncryptor`
<a name="ddb-net-itemencryptor"></a>

次の例は、下位レベルの `DynamoDbItemEncryptor` を [AWS KMS キーリング](use-kms-keyring.md)とともに使用して、テーブル項目を直接暗号化して署名する方法を示しています。`DynamoDbItemEncryptor` は項目を DynamoDB テーブルに配置しません。

DynamoDB 拡張クライアントではサポートされている任意の[キーリング](keyrings.md)を使用できますが、可能な限りいずれかの AWS KMS キーリングを使用することをお勧めします。

**注記**  
下位レベルの `DynamoDbItemEncryptor` は、[検索可能な暗号化](searchable-encryption.md)をサポートしていません。検索可能な暗号化を使用するには、低レベルの AWS Database Encryption SDK for DynamoDB API を使用します。

**完全なコードサンプル**「[ItemEncryptDecryptExample.cs](https://github.com/aws/aws-database-encryption-sdk-dynamodb/tree/main/Examples/runtimes/net/src/itemencryptor/ItemEncryptDecryptExample.cs)」を参照してください。

**ステップ 1: AWS KMS キーリングを作成する**  
次の例では、 `CreateAwsKmsMrkMultiKeyring`を使用して対称暗号化 KMS AWS KMS キーを持つ キーリングを作成します。`CreateAwsKmsMrkMultiKeyring` メソッドにより、キーリングは、単一リージョンのキーとマルチリージョンのキーの両方を確実に正しく処理します。  

```
var matProv = new MaterialProviders(new MaterialProvidersConfig());
var keyringInput = new CreateAwsKmsMrkMultiKeyringInput { Generator = kmsKeyId };
var 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`。

```
var attributeActionsOnEncrypt = new Dictionary<String, CryptoAction>
{
    ["partition_key"] = CryptoAction.SIGN_ONLY, // The partition attribute must be SIGN_ONLY
    ["sort_key"] = CryptoAction.SIGN_ONLY, // The sort attribute must be SIGN_ONLY
    ["attribute1"] = CryptoAction.ENCRYPT_AND_SIGN,
    ["attribute2"] = CryptoAction.SIGN_ONLY,
    [":attribute3"] = CryptoAction.DO_NOTHING
};
```

**ステップ 3: 署名から除外する属性を定義する**  
次の例では、すべての `DO_NOTHING` 属性が個別のプレフィックス「`:`」を共有し、そのプレフィックスを使用して、許可される署名なし属性を定義すると想定しています。クライアントは、「`:`」というプレフィックスが付いた属性名は署名から除外されると想定します。詳細については、「[Allowed unsigned attributes](ddb-net-using.md#net-allowed-unauth)」を参照してください。  

```
String unsignAttrPrefix = ":";
```

**ステップ 4: `DynamoDbItemEncryptor` 設定を定義する**  
次の例では、`DynamoDbItemEncryptor` の設定を定義します。  
この例では、DynamoDB テーブル名を[論理テーブル名](ddb-net-using.md#net-logical-table-name)として指定します。最初に暗号化設定を定義する際に、DynamoDB テーブル名を論理テーブル名として指定することを強くお勧めします。詳細については、「[AWS Database Encryption SDK for DynamoDB の暗号化設定](ddb-net-using.md#ddb-net-config-encrypt)」を参照してください。  

```
var config = new DynamoDbItemEncryptorConfig
{
    LogicalTableName = ddbTableName,
    PartitionKeyName = "partition_key",
    SortKeyName = "sort_key",
    AttributeActionsOnEncrypt = attributeActionsOnEncrypt,
    Keyring = kmsKeyring,
    AllowedUnsignedAttributePrefix = unsignAttrPrefix
};
```

**ステップ 5: `DynamoDbItemEncryptor` を作成する**  
次の例では、**ステップ 4** の `config` を使用して新しい `DynamoDbItemEncryptor` を作成します。  

```
var itemEncryptor = new DynamoDbItemEncryptor(config);
```

**ステップ 6: テーブル項目を直接暗号化して署名する**  
次の例では、`DynamoDbItemEncryptor` を使用して項目を直接暗号化し、署名します。`DynamoDbItemEncryptor` は項目を DynamoDB テーブルに配置しません。  

```
var originalItem = new Dictionary<String, AttributeValue>
{
    ["partition_key"] = new AttributeValue("ItemEncryptDecryptExample"),
    ["sort_key"] = new AttributeValue { N = "0" },
    ["attribute1"] = new AttributeValue("encrypt and sign me!"),
    ["attribute2"] = new AttributeValue("sign me!"),
    [":attribute3"] = new AttributeValue("ignore me!")
};

var encryptedItem = itemEncryptor.EncryptItem(
    new EncryptItemInput { PlaintextItem = originalItem }
).EncryptedItem;
```

# AWS Database Encryption SDK for DynamoDB を使用するように既存の DynamoDB テーブルを設定する
<a name="ddb-net-config-existing-table"></a>

DynamoDB 用の .NET クライアント側の暗号化ライブラリのバージョン 3.*x* では、クライアント側の暗号化用に既存の Amazon DynamoDB テーブルを設定できます。このトピックでは、データが入力されている既存の DynamoDB テーブルにバージョン 3.x を追加するために必要な 3 つのステップについてのガイダンスを提供します。

## ステップ 1: 暗号化された項目の読み取りと書き込みの準備をする
<a name="ddb-net-add-step1"></a>

Database Encryption SDK AWS クライアントが暗号化された項目を読み書きできるように準備するには、次の手順を実行します。次の変更をデプロイした後も、クライアントは引き続きプレーンテキスト項目の読み取りと書き込みを行います。テーブルに書き込まれる新しい項目の暗号化や署名は行いませんが、暗号化された項目が表示されるとすぐに復号できます。これらの変更により、クライアントが[新しい項目の暗号化](#ddb-net-add-step2)を開始するための準備が整います。次のステップに進む前に、次の変更を各リーダーにデプロイする必要があります。

**1. [属性アクション](concepts.md#crypt-actions)を定義する**  
オブジェクトモデルを作成して、暗号化および署名される属性値、署名のみされる属性値、および無視される属性値を定義します。  
デフォルトでは、プライマリキー属性は署名されてはいるが、暗号化されておらず (`SIGN_ONLY`)、他のすべての属性は暗号化されて署名されています (`ENCRYPT_AND_SIGN`)。  
属性を暗号化して署名するように `ENCRYPT_AND_SIGN` を指定します。属性に署名するが暗号化はしないように `SIGN_ONLY` を指定します。署名と属性`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`を指定し、暗号化コンテキストに含めます。属性に署名することなく、その属性を暗号化することはできません。属性を無視するように `DO_NOTHING` を指定します。詳細については、「[AWS Database Encryption SDK for DynamoDB の属性アクション](ddb-net-using.md#ddb-net-attribute-actions)」を参照してください。  
`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT` 属性を指定する場合、パーティション属性とソート属性も である必要があります`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`。

```
var attributeActionsOnEncrypt = new Dictionary<string, CryptoAction>
{
    ["partition_key"] = CryptoAction.SIGN_ONLY, // The partition attribute must be SIGN_ONLY
    ["sort_key"] = CryptoAction.SIGN_ONLY, // The sort attribute must be SIGN_ONLY
    ["attribute1"] = CryptoAction.ENCRYPT_AND_SIGN,
    ["attribute2"] = CryptoAction.SIGN_ONLY,
    [":attribute3"] = CryptoAction.DO_NOTHING
};
```

**2. 署名から除外する属性を定義する**  
次の例では、すべての `DO_NOTHING` 属性が個別のプレフィックス「`:`」を共有し、そのプレフィックスを使用して、許可される署名なし属性を定義すると想定しています。クライアントは、「`:`」というプレフィックスが付いた属性名は署名から除外されると想定します。詳細については、「[Allowed unsigned attributes](ddb-net-using.md#net-allowed-unauth)」を参照してください。  

```
const String unsignAttrPrefix = ":";
```

**3. [キーリング](keyrings.md)を作成します。**  
次の例では [AWS KMS キーリング](use-kms-keyring.md)を作成します。 AWS KMS キーリングは、対称暗号化または非対称 RSA AWS KMS keys を使用してデータキーを生成、暗号化、復号します。  
この例では、`CreateMrkMultiKeyring` を使用して、対称暗号化 KMS キーで AWS KMS キーリングを作成します。`CreateAwsKmsMrkMultiKeyring` メソッドにより、キーリングは、単一リージョンのキーとマルチリージョンのキーの両方を確実に正しく処理します。  

```
var matProv = new MaterialProviders(new MaterialProvidersConfig());
var keyringInput = new CreateAwsKmsMrkMultiKeyringInput { Generator = kmsKeyId };
var kmsKeyring = matProv.CreateAwsKmsMrkMultiKeyring(keyringInput);
```

**4. DynamoDB テーブルの暗号化設定を定義する **  
次の例では、この DynamoDB テーブルの暗号化設定を表す `tableConfigs` マップを定義します。  
この例では、DynamoDB テーブル名を[論理テーブル名](ddb-net-using.md#net-logical-table-name)として指定します。最初に暗号化設定を定義する際に、DynamoDB テーブル名を論理テーブル名として指定することを強くお勧めします。  
プレーンテキストのオーバーライドとして `FORCE_WRITE_PLAINTEXT_ALLOW_READ_PLAINTEXT` を指定する必要があります。このポリシーは、プレーンテキスト項目の読み取りと書き込みを継続し、暗号化された項目を読み取り、クライアントが暗号化された項目を書き込むための準備を整えます。  
テーブル暗号化設定に含まれる値の詳細については、「」を参照してください[AWS Database Encryption SDK for DynamoDB の暗号化設定](ddb-java-using.md#ddb-config-encrypt)。  

```
Dictionary<String, DynamoDbTableEncryptionConfig> tableConfigs =
    new Dictionary<String, DynamoDbTableEncryptionConfig>();
DynamoDbTableEncryptionConfig config = new DynamoDbTableEncryptionConfig
{
    LogicalTableName = ddbTableName,
    PartitionKeyName = "partition_key",
    SortKeyName = "sort_key",
    AttributeActionsOnEncrypt = attributeActionsOnEncrypt,
    Keyring = kmsKeyring,
    AllowedUnsignedAttributePrefix = unsignAttrPrefix,
    PlaintextOverride = FORCE_WRITE_PLAINTEXT_ALLOW_READ_PLAINTEXT
};
tableConfigs.Add(ddbTableName, config);
```

**5. 新しい AWS SDK DynamoDB クライアントを作成する**  
次の の例では、**ステップ 4** `TableEncryptionConfigs`の を使用して新しい AWS SDK DynamoDB クライアントを作成します。  

```
var ddb = new Client.DynamoDbClient(
    new DynamoDbTablesEncryptionConfig { TableEncryptionConfigs = tableConfigs });
```

## ステップ 2: 暗号化および署名された項目を書き込む
<a name="ddb-net-add-step2"></a>

テーブル暗号化設定のプレーンテキストポリシーを更新して、クライアントが暗号化および署名された項目を書き込むことを許可します。次の変更をデプロイすると、クライアントは**ステップ 1** で設定した属性アクションに基づいて新しい項目を暗号化して署名します。クライアントは、プレーンテキストの項目と暗号化および署名された項目を読み取ることができるようになります。

[ステップ 3](#ddb-net-add-step3) に進む前に、テーブル内の既存のすべてのプレーンテキスト項目を暗号化して署名する必要があります。既存のプレーンテキスト項目を迅速に暗号化するために実行できる単一のメトリクスやクエリはありません。システムにとって最も合理的なプロセスを使用してください。例えば、定義した属性アクションと暗号化設定を使用して、時間をかけてテーブルをスキャンし、項目を書き換える非同期プロセスを使用できます。テーブル内のプレーンテキスト項目を識別するには、 AWS Database Encryption SDK が暗号化および署名されたときに項目に追加する `aws_dbe_head`および `aws_dbe_foot` 属性を含まないすべての項目をスキャンすることをお勧めします。

次の の例では、**ステップ 1 **のテーブル暗号化設定を更新します。プレーンテキストのオーバーライドを `FORBID_WRITE_PLAINTEXT_ALLOW_READ_PLAINTEXT` を使用して更新する必要があります。このポリシーはプレーンテキスト項目を引き続き読み取りますが、暗号化された項目の読み取りと書き込みも行います。更新された を使用して新しい AWS SDK DynamoDB クライアントを作成します`TableEncryptionConfigs`。

```
Dictionary<String, DynamoDbTableEncryptionConfig> tableConfigs =
    new Dictionary<String, DynamoDbTableEncryptionConfig>();
DynamoDbTableEncryptionConfig config = new DynamoDbTableEncryptionConfig
{
    LogicalTableName = ddbTableName,
    PartitionKeyName = "partition_key",
    SortKeyName = "sort_key",
    AttributeActionsOnEncrypt = attributeActionsOnEncrypt,
    Keyring = kmsKeyring,
    AllowedUnsignedAttributePrefix = unsignAttrPrefix,
    PlaintextOverride = FORBID_WRITE_PLAINTEXT_ALLOW_READ_PLAINTEXT
};
tableConfigs.Add(ddbTableName, config);
```

## ステップ 3: 暗号化および署名された項目のみを読み取る
<a name="ddb-net-add-step3"></a>

すべての項目を暗号化して署名したら、テーブル暗号化設定のプレーンテキストオーバーライドを更新して、クライアントが暗号化および署名された項目の読み取りと書き込みのみを許可します。次の変更をデプロイすると、クライアントは**ステップ 1** で設定した属性アクションに基づいて新しい項目を暗号化して署名します。クライアントは、暗号化および署名された項目のみを読み取ることができます。

次の の例では、**ステップ 2 **のテーブル暗号化設定を更新します。`FORBID_WRITE_PLAINTEXT_FORBID_READ_PLAINTEXT` を使用してプレーンテキストオーバーライドを更新することも、設定からプレーンテキストポリシーを削除することもできます。クライアントは、デフォルトでは、暗号化および署名された項目の読み取りと書き込みのみを行います。更新された を使用して新しい AWS SDK DynamoDB クライアントを作成します`TableEncryptionConfigs`。

```
Dictionary<String, DynamoDbTableEncryptionConfig> tableConfigs =
    new Dictionary<String, DynamoDbTableEncryptionConfig>();
DynamoDbTableEncryptionConfig config = new DynamoDbTableEncryptionConfig
{
    LogicalTableName = ddbTableName,
    PartitionKeyName = "partition_key",
    SortKeyName = "sort_key",
    AttributeActionsOnEncrypt = attributeActionsOnEncrypt,
    Keyring = kmsKeyring,
    AllowedUnsignedAttributePrefix = unsignAttrPrefix,
    // Optional: you can also remove the plaintext policy from your configuration
    PlaintextOverride = FORBID_WRITE_PLAINTEXT_FORBID_READ_PLAINTEXT
};
tableConfigs.Add(ddbTableName, config);
```

# Rust
<a name="ddb-rust"></a>

このトピックでは、DynamoDB 用の Rust クライアント側の暗号化ライブラリのバージョン 1.*x* をインストールして使用する方法について説明します。 AWS Database Encryption SDK for DynamoDB を使用したプログラミングの詳細については、GitHub の aws-database-encryption-sdk-dynamodb リポジトリの [Rust の例](https://github.com/aws/aws-database-encryption-sdk-dynamodb/blob/main/releases/rust/db_esdk/examples/)を参照してください。

 AWS Database Encryption SDK for DynamoDB のすべてのプログラミング言語実装は相互運用可能です。

**Topics**
+ [前提条件](#ddb-rust-prerequisites)
+ [インストール](#ddb-rust-install)
+ [Rust クライアントの使用](ddb-rust-using.md)

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

DynamoDB 用の Rust クライアント側の暗号化ライブラリをインストールする前に、次の前提条件があることを確認してください。

**Rust と Cargo をインストールする**  
[rustup](https://rustup.rs/) を使用して [Rust](https://www.rust-lang.org/) の現在の安定リリースをインストールします。  
rustup のダウンロードとインストールの詳細については、「The Cargo Book」の[「インストール手順](https://doc.rust-lang.org/cargo/getting-started/installation.html)」を参照してください。

## インストール
<a name="ddb-rust-install"></a>

DynamoDB 用の Rust クライアント側の暗号化ライブラリは、Crates.io の [aws-db-esdk](https://crates.io/crates/aws-db-esdk) クレートとして利用できます。ライブラリのインストールと構築の詳細については、aws-database-encryption-sdk-dynamodb GitHub リポジトリの [README.md](https://github.com/aws/aws-database-encryption-sdk-dynamodb/) ファイルを参照してください。

**手動**  
DynamoDB 用の Rust クライアント側の暗号化ライブラリをインストールするには、[aws-database-encryption-sdk-dynamodb](https://github.com/aws/aws-database-encryption-sdk-dynamodb/) GitHub リポジトリのクローンを作成するか、ダウンロードします。

**最新バージョンをインストールするには**  
プロジェクトディレクトリで次の Cargo コマンドを実行します。  

```
cargo add aws-db-esdk
```
または、次の行を Cargo.toml に追加します。  

```
aws-db-esdk = "<version>"
```

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

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

DynamoDB 用の Rust クライアント側の暗号化ライブラリを使用したプログラミングの詳細については、GitHub の aws-database-encryption-sdk-dynamodb リポジトリの [Rust の例](https://github.com/aws/aws-database-encryption-sdk-dynamodb/blob/main/releases/rust/db_esdk/examples/)を参照してください。

**Topics**
+ [項目エンクリプタ](#ddb-rust-item-encryptors)
+ [属性アクション](#ddb-rust-attribute-actions)
+ [暗号化設定](#ddb-rust-config-encrypt)
+ [項目の更新](#ddb-rust-update-items)

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

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

**DynamoDB API 用の低レベル AWS データベース暗号化 SDK**  
[テーブル暗号化設定](#ddb-rust-config-encrypt)を使用して、DynamoDB `PutItem`リクエストでクライアント側で項目を自動的に暗号化して署名する DynamoDB クライアントを構築できます。  
[検索可能な](searchable-encryption.md)暗号化を使用するには、低レベルの AWS Database Encryption SDK for DynamoDB API を使用する必要があります。  
DynamoDB API 用の低レベルの AWS Database Encryption SDK の使用方法を示す例については、GitHub の aws-database-encryption-sdk-dynamodb リポジトリの [basic\$1get\$1put\$1example.rs](https://github.com/aws/aws-database-encryption-sdk-dynamodb/blob/main/releases/rust/db_esdk/examples/basic_get_put_example.rs) を参照してください。

**下位レベルの `DynamoDbItemEncryptor`**  
下位レベルの `DynamoDbItemEncryptor` は、DynamoDB を呼び出すことなく、テーブル項目を直接暗号化して署名するか、または復号して検証します。DynamoDB の `PutItem` または `GetItem` リクエストは実行しません。例えば、下位レベルの `DynamoDbItemEncryptor` を使用して、既に取得した DynamoDB 項目を直接復号して検証できます。  
下位レベルの `DynamoDbItemEncryptor` は、[検索可能な暗号化](searchable-encryption.md)をサポートしていません。  
下位レベルの の使用方法を示す例については`DynamoDbItemEncryptor`、GitHub の aws-database-encryption-sdk-dynamodb リポジトリの [item\$1encrypt\$1decrypt.rs](https://github.com/aws/aws-database-encryption-sdk-dynamodb/blob/main/releases/rust/db_esdk/examples/itemencryptor/item_encrypt_decrypt.rs) を参照してください。

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

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

Rust クライアントで属性アクションを指定するには、オブジェクトモデルを使用して属性アクションを手動で定義します。名前と値のペアが属性名と指定されたアクションを表す`HashMap`オブジェクトを作成して、属性アクションを指定します。

属性を暗号化して署名するように `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`。

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

次のオブジェクトモデルは`ENCRYPT_AND_SIGN`、Rust クライアントで `SIGN_ONLY`、`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`、、および `DO_NOTHING` 属性アクションを指定する方法を示しています。この例では、プレフィックス`:`「」を使用して`DO_NOTHING`属性を識別します。

```
let attribute_actions_on_encrypt = HashMap::from([
    ("partition_key".to_string(), CryptoAction::SignOnly),
    ("sort_key".to_string(), CryptoAction::SignOnly),
    ("attribute1".to_string(), CryptoAction::EncryptAndSign),
    ("attribute2".to_string(), CryptoAction::SignOnly),
    (":attribute3".to_string(), CryptoAction::DoNothing),
]);
```

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

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

次のスニペットは、低レベルの AWS Database Encryption SDK for DynamoDB API と、個別のプレフィックスで定義された許可された署名なし属性を使用して、DynamoDB テーブル暗号化設定を定義します。

```
let table_config = DynamoDbTableEncryptionConfig::builder()
    .logical_table_name(ddb_table_name)
    .partition_key_name("partition_key")
    .sort_key_name("sort_key")
    .attribute_actions_on_encrypt(attribute_actions_on_encrypt)
    .keyring(kms_keyring)
    .allowed_unsigned_attribute_prefix(UNSIGNED_ATTR_PREFIX)
    // Specifying an algorithm suite is optional
    .algorithm_suite_id(
        DbeAlgorithmSuiteId::AlgAes256GcmHkdfSha512CommitKeyEcdsaP384SymsigHmacSha384,
    )
    .build()?;

let table_configs = DynamoDbTablesEncryptionConfig::builder()
    .table_encryption_configs(HashMap::from([(ddb_table_name.to_string(), table_config)]))
    .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)を選択するには、テーブル暗号化設定に次のスニペットを含めます。  

```
.algorithm_suite_id(
    DbeAlgorithmSuiteId::AlgAes256GcmHkdfSha512CommitKeyEcdsaP384SymsigHmacSha384,
)
```

## AWS Database Encryption SDK を使用した項目の更新
<a name="ddb-rust-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` リクエストで既存の項目と同じプライマリキーを指定すると、新しい項目が既存の項目に完全に置き換わります。

# レガシー DynamoDB 暗号化クライアント
<a name="legacy-dynamodb-encryption-client"></a>

2023 年 6 月 9 日、クライアント側の暗号化ライブラリの名前が AWS Database Encryption SDK に変更されました。 AWS Database Encryption SDK は、引き続きレガシー DynamoDB 暗号化クライアントバージョンをサポートします。名前の変更によって変更されたクライアント側の暗号化ライブラリのさまざまな部分の詳細については、「[Amazon DynamoDB Encryption Client の名前の変更](DDBEC-rename.md)」を参照してください。

DynamoDB 用の Java クライアント側の暗号化ライブラリの最新バージョンに移行するには、「[バージョン 3.x に移行する](ddb-java-migrate.md)」を参照してください。

**Topics**
+ [AWS Database Encryption SDK for DynamoDB バージョンのサポート](#legacy-support)
+ [DynamoDB 暗号化クライアントの仕組み](DDBEC-legacy-how-it-works.md)
+ [Amazon DynamoDB Encryption Client の概念](DDBEC-legacy-concepts.md)
+ [暗号マテリアルプロバイダー](crypto-materials-providers.md)
+ [Amazon DynamoDB Encryption Client で利用可能なプログラミング言語](programming-languages.md)
+ [データモデルの変更](data-model.md)
+ [DynamoDB 暗号化クライアントアプリケーションの問題のトラブルシューティング](troubleshooting.md)

## AWS Database Encryption SDK for DynamoDB バージョンのサポート
<a name="legacy-support"></a>

「レガシー」の章のトピックには、DynamoDB Encryption Client for Java のバージョン 1.x～2.x および DynamoDB Encryption Client for Python のバージョン 1.x～3.x に関する情報が記載されています。

次の表には、Amazon DynamoDB でクライアント側の暗号化をサポートする言語とバージョンがリストされています。


| プログラミング言語 | バージョン | SDK メジャーバージョンのライフサイクルフェーズ | 
| --- | --- | --- | 
|  Java  |  バージョン 1.x  |  [サポート終了フェーズ](https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html#version-life-cycle)、2022 年 7 月発効  | 
|  Java  |  バージョン 2.x  |  [一般提供](https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html#version-life-cycle) (GA)  | 
|  Java  |  バージョン 3.x  |  [一般提供](https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html#version-life-cycle) (GA)  | 
|  Python  |  バージョン 1.x  |  [サポート終了フェーズ](https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html#version-life-cycle)、2022 年 7 月発効  | 
|  Python  |  バージョン 2.x  |  [サポート終了フェーズ](https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html#version-life-cycle)、2022 年 7 月発効  | 
|  Python  |  バージョン 3.x  |  [一般提供](https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html#version-life-cycle) (GA)  | 

# DynamoDB 暗号化クライアントの仕組み
<a name="DDBEC-legacy-how-it-works"></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)」を参照してください。

DynamoDB 暗号化クライアントは、DynamoDB に保存されているデータを保護するように特別に設計されています。ライブラリには、拡張が可能でまた変更なしで使用できる安全な実装が含まれています。また、ほとんどの要素は抽象要素で表されるため、互換性のあるカスタムコンポーネントを作成して使用できます。

**テーブル項目の暗号化と署名**

DynamoDB 暗号化クライアントの中核には、テーブル項目を暗号化、署名、検証、復号する*項目エンクリプタ*があります。テーブル項目に関する情報と、暗号化して署名する項目に関する指示が取り込まれます。選択して設定した[暗号化マテリアルプロバイダー](DDBEC-legacy-concepts.md#concept-material-provider)から、暗号化マテリアルとその使用方法に関する指示が取得されます。

次の図は、このプロセスの高レベルのビューを示しています。

![\[DynamoDB 暗号化クライアントでの項目の暗号化と署名\]](http://docs.aws.amazon.com/ja_jp/database-encryption-sdk/latest/devguide/images/arch-encrypt.png)


テーブル項目を暗号化して署名するには、DynamoDB 暗号化クライアントに次のものが必要です。
+ **テーブルについての情報。**お客様が提供する [DynamoDB 暗号化コンテキスト](concepts.md#encryption-context)からテーブルに関する情報を取得します。一部のヘルパーは、DynamoDB から必要な情報を取得し、DynamoDB 暗号化コンテキストを作成します。
**注記**  
*DynamoDB 暗号化クライアントの DynamoDB 暗号化コンテキスト*は、 AWS Key Management Service (AWS KMS) および の*暗号化コンテキスト*とは関係ありません AWS Encryption SDK。 DynamoDB 
+ **暗号化して署名する属性。**この情報は、指定した[属性アクション](DDBEC-legacy-concepts.md#legacy-attribute-actions)から取得されます。
+ **暗号化および署名キーを含む、暗号化マテリアル。**これらは、お客様が選択して設定する[暗号化マテリアルプロバイダー](DDBEC-legacy-concepts.md#concept-material-provider) (CMP) から取得されます。
+ **項目の暗号化と署名の手順**。CMP は、暗号化および署名アルゴリズムを含む、暗号化マテリアルを使用するための指示を[実際のマテリアル説明](DDBEC-legacy-concepts.md#legacy-material-description)に追加します。

[項目エンクリプタ](DDBEC-legacy-concepts.md#item-encryptor)は、これらの要素のすべてを使用して項目を暗号化して署名します。項目エンクリプタは、暗号化と署名の指示 (実際のマテリアル説明) を含む[マテリアル説明属性](DDBEC-legacy-concepts.md#legacy-material-description)と、その署名を含む属性を項目に追加します。項目エンクリプタと直接やり取りすることができます。また、項目エンクリプタとやり取りするヘルパー機能を使用して、安全なデフォルトの動作を実装することもできます。

結果は、暗号化された署名済みデータを含む DynamoDB 項目です。

**テーブル項目の検証と復号**

これらのコンポーネントは、次の図に示すように、項目を検証および復号するために一緒に機能します。

![\[DynamoDB 暗号化クライアントでの項目の検証と復号\]](http://docs.aws.amazon.com/ja_jp/database-encryption-sdk/latest/devguide/images/arch-decrypt.png)


項目を検証し、復号するためには、DynamoDB 暗号化クライアントには、次のように、同じコンポーネント、同じ設定のコンポーネント、または項目を復号するために特に設計されたコンポーネントが必要です。
+ [DynamoDB 暗号化コンテキスト](concepts.md#encryption-context)からの**テーブルに関する情報**。
+ **検証および復号する属性。**これらは[属性アクション](DDBEC-legacy-concepts.md#legacy-attribute-actions)から取得されます。
+ **選択し、設定した**[暗号化マテリアルプロバイダー](DDBEC-legacy-concepts.md#concept-material-provider) (CMP) からの検証キーおよび復号キーを含む復号マテリアル。

  暗号化された項目には、暗号化に使用された CMP のレコードは含まれません。同じ CMP、同じ設定の CMP、または項目を復号するように設計された CMP 指定する必要があります。
+ 暗号化アルゴリズムと署名アルゴリズムを含む、**項目の暗号化と項目の署名に関する情報**。クライアントは、項目の[マテリアル説明属性](DDBEC-legacy-concepts.md#legacy-material-description)からこれらを取得します。

[項目エンクリプタ](DDBEC-legacy-concepts.md#item-encryptor)は、これらの要素のすべてを使用して項目の検証と復号を行います。また、マテリアル記述と署名属性も削除されます。結果はプレーンテキスト DynamoDB 項目です。

# Amazon DynamoDB Encryption Client の概念
<a name="DDBEC-legacy-concepts"></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 で使用されている概念と用語について説明します。

DynamoDB 暗号化クライアントのコンポーネントがやり取りする方法については、[DynamoDB 暗号化クライアントの仕組み](DDBEC-legacy-how-it-works.md) を参照してください。

**Topics**
+ [暗号化マテリアルプロバイダー (CMP)](#concept-material-provider)
+ [項目エンクリプタ](#item-encryptor)
+ [属性アクション](#legacy-attribute-actions)
+ [マテリアル記述](#legacy-material-description)
+ [DynamoDB 暗号化コンテキスト](#legacy-encryption-context)
+ [プロバイダーストア](#provider-store)

## 暗号化マテリアルプロバイダー (CMP)
<a name="concept-material-provider"></a>

DynamoDB 暗号化クライアントの実装時に、最初のタスクの 1 つとして、[暗号化マテリアルプロバイダー (CMP)](crypto-materials-providers.md) (*暗号化マテリアルプロバイダー*とも呼ばれる) の選択があります。残りの実装の多くは、この選択によって決まります。

*暗号化マテリアルプロバイダー* (CMP) は[項目エンクリプタ](#item-encryptor)が、テーブル項目を暗号化し署名するのに使用する暗号化マテリアルを収集、アセンブルし、返します。CMP は、使用する暗号化アルゴリズムと、暗号化キーと署名キーを生成して保護する方法を決定します。

CMP は項目エンクリプタとやり取りします。項目エンクリプタは、暗号化または復号マテリアルを CMP に要求し、CMP はそれを項目エンクリプタに返します。次に、項目エンクリプタは、暗号化マテリアルを使用して、項目の暗号化、署名、検証、および復号を行います。

CMP は、クライアントの設定時に指定します。互換性のあるカスタム CMP を作成するか、ライブラリ内の多くの CMP のいずれかを使用できます。ほとんどの CMP は、複数のプログラミング言語で使用できます。

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

*項目エンクリプタ*は、DynamoDB 暗号化クライアントの暗号化オペレーションを実行する低レベルのコンポーネントです。項目エンクリプタは、[暗号化マテリアルプロバイダー](#concept-material-provider) (CMP) に暗号化マテリアルをリクエストし、CMP より返るマテリアルを使用して、テーブル項目を暗号化して署名するか、検証して復号します。

項目エンクリプタと直接やり取りするか、ライブラリにあるヘルパーを使用することができます。例えば、Java 用 DynamoDB 暗号化クライアントには、`DynamoDBMapper` で使用できる `AttributeEncryptor` ヘルパークラスが含まれています。`DynamoDBEncryptor` 項目エンクリプタとは直接やり取りしません。Python ライブラリには、項目エンクリプタとやり取りする、`EncryptedTable`、`EncryptedClient`、および `EncryptedResource` ヘルパークラスが含まれています。

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

*属性アクション*は、項目の各属性に対して実行するアクションを項目エンクリプタに指示します。

属性アクションの値は、次のいずれかの値になります。
+ **暗号化と署名** –属性値を暗号化します。項目の署名に属性 (名前と値) を含めます。
+ **署名のみ** - 項目署名に属性を含めます。
+ **何もしない** - 属性に対して暗号化と署名のいずれも行いません。

機密データを保存できるすべての属性は、**暗号化と署名**を使用します。プライマリキー属性 (パーティションキーとソートキー) は、**署名のみ**を使用します。[マテリアル説明属性](#legacy-material-description)および署名属性は、署名も暗号化もされていません。これらの属性の属性アクションを指定する必要はありません。

属性アクションを慎重に選択します。不確かな場合は、**暗号化と署名**を使用します。DynamoDB 暗号化クライアントを使用してテーブル項目を保護した後は、署名検証エラーのリスクを冒すことなく、属性のアクションを変更することはできません。詳細については、「[データモデルの変更](data-model.md)」を参照してください。

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

[DynamoDB 暗号化コンテキスト](concepts.md#encryption-context)がプライマリキー属性を識別する場合、それらを暗号化しようとするとクライアントはエラーをスローします。

属性アクションの指定に使用する手法は、プログラミング言語ごとに異なります。また、使用するヘルパークラスに固有の場合もあります。

詳細については、使用しているプログラミング言語のドキュメントを参照してください。
+ [Python](python-using.md#python-attribute-actions)
+ [Java](java-using.md#attribute-actions-java)

## マテリアル記述
<a name="legacy-material-description"></a>

暗号化されたテーブル項目の*マテリアル説明*は、暗号化アルゴリズムなどの情報で構成されます。この情報は、テーブル項目が暗号化および署名される仕組みに関するものです。[暗号化マテリアルプロバイダー](#concept-material-provider) (CMP) は、暗号化し、署名するための暗号化マテリアルをアセンブルするときに、マテリアル説明を記録します。後で、項目を検証および復号するために暗号化されたマテリアルをアセンブルする必要がある場合は、そのマテリアル記述をガイドとして使用します。

DynamoDB 暗号化クライアントでは、マテリアル記述は 3 つの関連する要素について参照します。

**リクエストされたマテリアル説明**  
[暗号化マテリアルプロバイダー](#concept-material-provider) (CMP) によっては、暗号化アルゴリズムなどの高度なオプションを指定できます。選択肢を示すために、テーブル項目を暗号化するリクエストの [DynamoDB 暗号化コンテキスト](concepts.md#encryption-context)のマテリアル説明プロパティに名前と値のペアを追加します。この要素は、*リクエストされたマテリアル説明*と呼ばれます。リクエストされたマテリアル記述の有効値は、選択した CMP によって定義されます。  
マテリアル記述は安全なデフォルト値を上書きできるため、やむを得ない理由がない限り、リクエストされたマテリアル記述を省略することをお奨めします。

**実際のマテリアル記述**  
[暗号化マテリアルプロバイダー](#concept-material-provider) (CMP) が返すマテリアル説明は、*実際のマテリアル説明*と呼ばれます。CMP が暗号化マテリアルを構築したときに使用した実際の値について説明します。また、通常、リクエストされたマテリアル記述で構成され、ある場合は追加と変更を含みます。

**マテリアル記述属性**  
クライアントは、実際のマテリアル説明を暗号化項目の*マテリアル説明属性*に保存します。このマテリアル記述属性名は、`amzn-ddb-map-desc` で、その値は実際のマテリアル記述です。クライアントは、マテリアル記述属性の値を使用して、項目の検証および復号を行います。

## DynamoDB 暗号化コンテキスト
<a name="legacy-encryption-context"></a>

*DynamoDB 暗号化コンテキスト*は、テーブルと項目に関する情報を[暗号化マテリアルプロバイダー](#concept-material-provider) (CMP) に提供します。高度な実装では、DynamoDB 暗号化コンテキストに、[リクエストされたマテリアルの説明](#legacy-material-description)を含めることができます。

テーブル項目を暗号化すると、DynamoDB 暗号化コンテキストが暗号化された属性値に暗号でバインドされます。復号時に、DynamoDB 暗号化コンテキストが暗号化に使用された DynamoDB 暗号化コンテキストに対して大文字と小文字を区別して完全に一致しない場合、復号オペレーションは失敗します。[項目エンクリプタ](#item-encryptor)と直接やり取りする場合は、暗号化メソッドまたは復号メソッドを呼び出すときに DynamoDB 暗号化コンテキストを提供する必要があります。ほとんどのヘルパーは、DynamoDB 暗号化コンテキストを作成します。

**注記**  
*DynamoDB 暗号化クライアントの DynamoDB 暗号化コンテキスト*は、 AWS Key Management Service (AWS KMS) および の*暗号化コンテキスト*とは関係ありません AWS Encryption SDK。 DynamoDB 

DynamoDB 暗号化のコンテキストによって次のフィールドを含めることができます。すべてのフィールドと値はオプションです。
+ テーブル名
+ パーティションキー名
+ ソートキー名
+ 属性名と値のペア
+ [リクエストされたマテリアル説明](#legacy-material-description)

## プロバイダーストア
<a name="provider-store"></a>

*プロバイダーストア*は、[暗号化マテリアルプロバイダー](#concept-material-provider) (CMP) を返すコンポーネントです。プロバイダーストアは、CMP を作成するか、別のプロバイダーストアなどの別のソースから CMP を取得できます。プロバイダーストアは、作成した CMP のバージョンを、保存されたそれぞれの CMP がリクエスタのマテリアル名とバージョン番号によって識別される永続的ストレージに保存します。

DynamoDB 暗号化クライアントの[最新プロバイダー](most-recent-provider.md)はプロバイダーストアから CMP を取得しますが、プロバイダーストアを使用して任意のコンポーネントに CMP を提供できます。各最新のプロバイダーは 1 つのプロバイダーストアに関連付けられていますが、プロバイダーストアは複数のホスト間で多くのリクエスタに CMP を提供できます。

プロバイダーストアは、オンデマンドで新しいバージョンの CMP を作成し、新しいバージョンと既存のバージョンを返します。また、指定されたマテリアル名の最新バージョン番号も返されます。これにより、リクエスタは、プロバイダーストアからリクエストできる新しいバージョンの CMP がリリースされるタイミングを把握することができます。

DynamoDB 暗号化クライアントには [MetaStore](most-recent-provider.md#about-metastore) が含まれています。これは、DynamoDB に保管され、内部 DynamoDB 暗号化クライアントを使用して暗号化されたキーを使用してラップされた CMP を作成するプロバイダーストアです。

**詳細はこちら:**
+ プロバイダーストア: [Java](https://aws.github.io/aws-dynamodb-encryption-java/com/amazonaws/services/dynamodbv2/datamodeling/encryption/providers/store/ProviderStore.html)、[Python](https://github.com/aws/aws-dynamodb-encryption-python/blob/master/src/dynamodb_encryption_sdk/material_providers/store/__init__.py)
+ MetaStore: [Java](https://aws.github.io/aws-dynamodb-encryption-java/com/amazonaws/services/dynamodbv2/datamodeling/encryption/providers/store/MetaStore.html)、[Python](https://aws-dynamodb-encryption-python.readthedocs.io/en/latest/lib/materials_providers/metastore.html#module-dynamodb_encryption_sdk.material_providers.store.meta)

# 暗号マテリアルプロバイダー
<a name="crypto-materials-providers"></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)」を参照してください。

DynamoDB 暗号化クライアントを使用する場合に最も重要となる決定事項の 1 つは、[暗号化マテリアルプロバイダー](DDBEC-legacy-concepts.md#concept-material-provider) (CMP) の選択です。CMP は、暗号化マテリアルをアセンブルして、項目エンクリプタに返します。また、暗号化キーと署名キーの生成方法、新しいキーマテリアルが項目ごとに生成されるか、または再利用されるか、使用する暗号化アルゴリズムおよび署名アルゴリズムも指定されます。

DynamoDB 暗号化クライアントライブラリに含まれている実装から CMP を選択するか、互換性のあるカスタム CMP を構築できます。また、CMP の選択も、使用する[プログラミング言語](programming-languages.md)によって異なります。

このトピックでは、一般的な CMP について説明するとともに、アプリケーションに最適な CMP を選択するのに役立ついくつかのアドバイスを提供します。

**Direct KMS マテリアルプロバイダー**  
Direct KMS マテリアルプロバイダーは、[AWS KMS key](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys) によってテーブル項目を保護しているため、[AWS Key Management Service](https://docs.aws.amazon.com/kms/latest/developerguide/) (AWS KMS) は必ず暗号化されます。アプリケーションで、暗号化マテリアルを生成または管理する必要はありません。を使用して項目ごとに一意の暗号化キーと署名キー AWS KMS key を生成するため、このプロバイダーは項目を暗号化または復号する AWS KMS たびに を呼び出します。  
を使用し AWS KMS 、トランザクションごとに 1 回の AWS KMS 呼び出しがアプリケーションで実用的である場合、このプロバイダーが適しています。  
詳細については、「[Direct KMS マテリアルプロバイダー](direct-kms-provider.md)」を参照してください。

**ラップされたマテリアルプロバイダー (ラップされた CMP)**  
ラップされたマテリアルプロバイダー (ラップされた CMP) では、DynamoDB 暗号化クライアントの外部で、ラッピングおよび署名キーを生成および管理することができます。  
ラップされた CMP は、項目ごとに一意の暗号化キーを生成します。次に、生成したラップキー (またはアンラップキー) および署名キーを使用します。したがって、ラップキーおよび署名キーの生成方法と、それらが各項目に一意か、または再利用されたものかを判断します。ラップされた CMP は、 を使用せず、暗号化マテリアルを安全に管理 AWS KMS できるアプリケーション用の [Direct KMS プロバイダー](direct-kms-provider.md)の安全な代替手段です。  
詳細については、「[ラップされたマテリアルプロバイダー](wrapped-provider.md)」を参照してください。

**最新プロバイダー**  
*最新プロバイダー*は、[プロバイダーストア](DDBEC-legacy-concepts.md#provider-store)で機能するように設計された[暗号化マテリアルプロバイダー](DDBEC-legacy-concepts.md#concept-material-provider) (CMP) です。プロバイダーストアから CMP を取得し、CMP から返る暗号化マテリアルを取得します。最新プロバイダーでは通常、各 CMP を使用して暗号化マテリアルの複数の要求を満たしますが、プロバイダーストアの機能を使用して、マテリアルの再利用範囲を制御したり、CMP の回転頻度を判断したりできるほか、最新プロバイダーを変更せずに使用される CMP のタイプを変更することもできます。  
最新プロバイダーは互換性のあるプロバイダーストアで使用できます。DynamoDB 暗号化クライアントには、ラップされた CMP を返すプロバイダーストアである MetaStore が含まれています。  
最新プロバイダーは、その暗号ソースへの呼び出しを最小限に抑える必要のあるアプリケーションや、セキュリティ要件に違反せずに一部の暗号化マテリアルを再利用できるアプリケーションに適しています。たとえば、項目を暗号化または復号する AWS KMS たびに を呼び出すことなく、 [AWS KMS key](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys) [AWS Key Management Service](https://docs.aws.amazon.com/kms/latest/developerguide/) (AWS KMS) の で暗号化マテリアルを保護できます。  
詳細については、「[最新プロバイダー](most-recent-provider.md)」を参照してください。

**静的マテリアルプロバイダー**  
静的マテリアルプロバイダーは、検証や概念実証のデモンストレーション、および従来の互換性を目的として設計されています。項目ごとに一意の暗号化マテリアルが生成されることはありません。指定した暗号化キーと署名キーが返ります。これらのキーは、テーブル項目の暗号化、復号、および署名に直接使用されます。  
Java ライブラリ内の[非対称静的プロバイダー](https://aws.github.io/aws-dynamodb-encryption-java/com/amazonaws/services/dynamodbv2/datamodeling/encryption/providers/AsymmetricStaticProvider.html)は静的プロバイダーではありません。これは、[ラップされた CMP](wrapped-provider.md) の代替コンストラクタを指定するだけです。本稼働環境での使用は安全ですが、できるだけラップされた CMP を直接使用する必要があります。

**Topics**
+ [Direct KMS マテリアルプロバイダー](direct-kms-provider.md)
+ [ラップされたマテリアルプロバイダー](wrapped-provider.md)
+ [最新プロバイダー](most-recent-provider.md)
+ [静的マテリアルプロバイダー](static-provider.md)

# Direct KMS マテリアルプロバイダー
<a name="direct-kms-provider"></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)」を参照してください。

*Direct KMS マテリアルプロバイダー* (Direct KMS プロバイダー) は、[AWS KMS key](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys) によってテーブル項目を保護しているため、[AWS Key Management Service](https://docs.aws.amazon.com/kms/latest/developerguide/) (AWS KMS) は必ず暗号化されます。この[暗号化マテリアルプロバイダー](DDBEC-legacy-concepts.md#concept-material-provider)より、テーブル項目ごとに一意の暗号化キーと署名キーが返ります。そのためには、項目を暗号化または復号する AWS KMS たびに を呼び出します。

DynamoDB 項目を高頻度かつ大規模に処理している場合、1 AWS KMS [requests-per-second数の制限](https://docs.aws.amazon.com/kms/latest/developerguide/limits.html#requests-per-second)を超えると、処理の遅延が発生する可能性があります。制限を超過する必要がある場合は、[AWS サポート センター](https://console.aws.amazon.com/support/home)でケースを作成してください。また、[最新プロバイダー](most-recent-provider.md)など、キーの再利用が制限された暗号化マテリアルプロバイダーの使用を検討することもできます。

Direct KMS プロバイダーを使用するには、発信者に、 [AWS アカウント](https://aws.amazon.com/premiumsupport/knowledge-center/create-and-activate-aws-account/)で [GenerateDataKey](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKey.html) および [Decrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.html) オペレーションを呼び出すための 、少なくとも 1 つの AWS KMS key、および アクセス許可が必要です AWS KMS key。 AWS KMS key は対称暗号化キーである必要があります。DynamoDB 暗号化クライアントは非対称暗号化をサポートしていません。[DynamoDB グローバルテーブル](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GlobalTables.html)を使用している場合、[AWS KMS マルチリージョンキー](https://docs.aws.amazon.com/kms/latest/developerguide/multi-region-keys-overview.html)を指定することもできます。詳細については、「[使用方法](#provider-kms-how-to-use)」を参照してください。

**注記**  
Direct KMS プロバイダーを使用すると、プライマリキー属性の名前と値は、関連する AWS KMS オペレーションの[AWS KMS 暗号化コンテキスト](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#encrypt_context)と AWS CloudTrail ログにプレーンテキストで表示されます。ただし、DynamoDB 暗号化クライアントが、暗号化された属性値をプレーンテキストで公開することはありません。

Direct KMS プロバイダーは、DynamoDB 暗号化クライアントがサポートしている複数の[暗号化マテリアルプロバイダー](DDBEC-legacy-concepts.md#concept-material-provider) (CMP) の 1 つです。他の CMP の詳細については、「[暗号マテリアルプロバイダー](crypto-materials-providers.md)」を参照してください。

**サンプルコードについては、以下を参照してください。**
+ Java: [AwsKmsEncryptedItem](https://github.com/aws/aws-dynamodb-encryption-java/blob/master/examples/src/main/java/com/amazonaws/examples/AwsKmsEncryptedItem.java)
+ Python: [aws-kms-encrypted-table](https://github.com/aws/aws-dynamodb-encryption-python/blob/master/examples/src/dynamodb_encryption_sdk_examples/aws_kms_encrypted_table.py)、[aws-kms-encrypted-item](https://github.com/aws/aws-dynamodb-encryption-python/blob/master/examples/src/dynamodb_encryption_sdk_examples/aws_kms_encrypted_item.py)

**Topics**
+ [使用方法](#provider-kms-how-to-use)
+ [仕組み](#provider-kms-how-it-works)

## 使用方法
<a name="provider-kms-how-to-use"></a>

Direct KMS プロバイダーを作成するには、キー ID パラメータを使用して、アカウントに対称暗号化 [KMS キー](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys)を指定します。キー ID パラメータの値は、キー ID、キー ARN、エイリアス名、または AWS KMS keyのエイリアス ARN にすることができます。キー ID の詳細については、*AWS Key Management Service デベロッパーガイド*の「[キー識別子](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id)」を参照してください。

Direct KMS プロバイダーでは、対称暗号化 KMS キーが必要です。非対称 KMS キーを使用することはできません。ただし、マルチリージョン KMS キー、インポートされたキーマテリアルを含む KMS キー、またはカスタムキーストア内の KMS キーを使用できます。KMS キーに [kms:GenerateDataKey](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKey.html) アクセス許可と [kms:Decrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.html) アクセス許可がある必要があります。そのため、 マネージドまたは AWS 所有の KMS キーではなく、カスタマー AWS マネージドキーを使用する必要があります。

DynamoDB Encryption Client for Python は、キー ID パラメータ値にリージョンが含まれている場合、そのリージョン AWS KMS から呼び出すリージョンを決定します。それ以外の場合は、 AWS KMS クライアントでリージョンを指定するか、 で設定したリージョンを使用します AWS SDK for Python (Boto3)。Python でのリージョンの選択については、 AWS SDK for Python (Boto3) API リファレンスの[「設定](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/configuration.html)」を参照してください。

Java 用 DynamoDB 暗号化クライアントは、指定したクライアントにリージョンが含まれている場合、クライアントのリージョン AWS KMS AWS KMS から呼び出すリージョンを決定します。リージョンが含まれていない場合、 AWS SDK for Javaで設定されたリージョンが使用されます。でのリージョンの選択については AWS SDK for Java、「 AWS SDK for Java デベロッパーガイド」の[AWS リージョン 「選択](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/java-dg-region-selection.html)」を参照してください。

------
#### [ Java ]

```
// Replace the example key ARN and Region with valid values for your application
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);
```

------
#### [ Python ]

次の例では、キー ARN を使用して AWS KMS keyを指定しています。キー識別子に が含まれていない場合 AWS リージョン、DynamoDB 暗号化クライアントは、設定された Botocore セッションがある場合、または Boto のデフォルトからリージョンを取得します。

```
# Replace the example key ID with a valid value
kms_key = 'arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab'
kms_cmp = AwsKmsCryptographicMaterialsProvider(key_id=kms_key)
```

------

[Amazon DynamoDB グローバルテーブル](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GlobalTables.html)を使用している場合は、 AWS KMS マルチリージョンキーでデータを暗号化することをお勧めします。マルチリージョンキーは異なる AWS KMS keys にあり AWS リージョン 、同じキー ID とキーマテリアルを持つため、同じ意味で使用できます。詳細については、*AWS Key Management Service デベロッパーガイド*の「[マルチリージョンキーを使用する](https://docs.aws.amazon.com/kms/latest/developerguide/multi-region-keys-overview.html)」を参照してください。

**注記**  
グローバルテーブルの[バージョン 2017.11.29](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/globaltables.V1.html) を使用している場合は、予約されたレプリケーションフィールドが暗号化または署名されないように属性アクションを設定する必要があります。詳細については、「[古いバージョンのグローバルテーブルの問題](troubleshooting.md#fix-global-tables)」を参照してください。

DynamoDB 暗号化クライアントでマルチリージョンキーを使用するには、マルチリージョンキーを作成し、アプリケーションを実行するリージョンにレプリケートします。次に、DynamoDB 暗号化クライアントが AWS KMSを呼び出すリージョンでマルチリージョンキーを使用するように Direct KMS プロバイダーを設定します。

次の例では、マルチリージョンキーを使用して、米国東部 (バージニア北部) (us-east-1) リージョンのデータを暗号化し、米国西部 (オレゴン) (us-west-2) リージョンのデータを復号するように DynamoDB 暗号化クライアントを設定します。

------
#### [ Java ]

この例では、DynamoDB 暗号化クライアントは、 AWS KMS クライアントの リージョン AWS KMS から を呼び出すための リージョンを取得します。`keyArn` 値は、同じリージョンのマルチリージョンキーを識別します。

```
// Encrypt in us-east-1

// Replace the example key ARN and Region with valid values for your application
final String usEastKey = 'arn:aws:kms:us-east-1:111122223333:key/mrk-1234abcd12ab34cd56ef1234567890ab'
final String region = 'us-east-1'
      
final AWSKMS kms = AWSKMSClientBuilder.standard().withRegion(region).build();
final DirectKmsMaterialProvider cmp = new DirectKmsMaterialProvider(kms, usEastKey);
```

```
// Decrypt in us-west-2

// Replace the example key ARN and Region with valid values for your application
final String usWestKey = 'arn:aws:kms:us-west-2:111122223333:key/mrk-1234abcd12ab34cd56ef1234567890ab'
final String region = 'us-west-2'
      
final AWSKMS kms = AWSKMSClientBuilder.standard().withRegion(region).build();
final DirectKmsMaterialProvider cmp = new DirectKmsMaterialProvider(kms, usWestKey);
```

------
#### [ Python ]

この例では、DynamoDB 暗号化クライアントは、キー ARN のリージョン AWS KMS から を呼び出すためのリージョンを取得します。

```
# Encrypt in us-east-1

# Replace the example key ID with a valid value
us_east_key = 'arn:aws:kms:us-east-1:111122223333:key/mrk-1234abcd12ab34cd56ef1234567890ab'
kms_cmp = AwsKmsCryptographicMaterialsProvider(key_id=us_east_key)
```

```
# Decrypt in us-west-2

# Replace the example key ID with a valid value
us_west_key = 'arn:aws:kms:us-west-2:111122223333:key/mrk-1234abcd12ab34cd56ef1234567890ab'
kms_cmp = AwsKmsCryptographicMaterialsProvider(key_id=us_west_key)
```

------

## 仕組み
<a name="provider-kms-how-it-works"></a>

以下の図に示されているように、Direct KMS プロバイダーは、指定した AWS KMS key で保護されている暗号化キーおよび署名キーを返します。

![\[DynamoDB 暗号化クライアントでの Direct KMS プロバイダーの入力、処理、および出力\]](http://docs.aws.amazon.com/ja_jp/database-encryption-sdk/latest/devguide/images/directKMS.png)

+ 暗号化マテリアルを生成するために、Direct KMS プロバイダーは、指定した を使用して項目ごとに[一意のデータキーを生成する](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKey.html) AWS KMS ように に求め AWS KMS key ます。これにより、[データキー](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#data-keys)のプレーンテキストコピーから項目の暗号化キーと署名キーが導出され、暗号化データキーと一緒に返ります。このデータキーは、項目の[マテリアル記述属性](DDBEC-legacy-concepts.md#legacy-material-description)に保存されます。

  項目エンクリプタでは、この暗号化キーおよび署名キーを使用します。また、メモリから可能な限り早くそれらを削除します。導出されたデータキーの暗号化されたコピーのみ、暗号化された項目に保存されます。
+ 復号マテリアルを生成するために、Direct KMS プロバイダーは暗号化されたデータキーを復号 AWS KMS するように に求めます。これにより、プレーンテキストデータキーより検証キーおよび署名キーが導出され、項目エンクリプタに返されます。

  項目エンクリプタは項目を検証し、検証が成功すると、暗号化された値が復号されます。次に、可能な限り早く、メモリよりキーが削除されます。

### 暗号化マテリアルを取得する
<a name="direct-kms-get-encryption-materials"></a>

このセクションでは、[項目エンクリプタ](DDBEC-legacy-concepts.md#item-encryptor)より暗号化マテリアルのリクエストを受け取るときの Direct KMS プロバイダーの入力、出力、処理の詳細について説明します。

**入力** (アプリケーションから)
+ のキー ID AWS KMS key。

**入力** (項目エンクリプタから)
+ [DynamoDB 暗号化コンテキスト](concepts.md#encryption-context)

**出力** (項目エンクリプタへ)
+ 暗号化キー (プレーンテキスト)
+ 署名キー
+ [実際のマテリアル説明](DDBEC-legacy-concepts.md#legacy-material-description)で、これらの値は、クライアントより項目に追加されるマテリアル説明属性に保存されます。
  + amzn-ddb-env-key: によって暗号化された Base64-encodedされたデータキー AWS KMS key
  + amzn-ddb-env-alg: 暗号化アルゴリズム。デフォルトは [AES/256](https://csrc.nist.gov/projects/cryptographic-standards-and-guidelines/archived-crypto-projects/aes-development)
  + amzn-ddb-sig-alg: 署名アルゴリズム。デフォルトは [HmacSHA256/256](https://en.wikipedia.org/wiki/HMAC)
  + amzn-ddb-wrap-alg: kms

**Processing**

1. Direct KMS プロバイダー AWS KMS は、指定された を使用して項目の一意のデータキー AWS KMS key を生成するリクエストを送信します。 [https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKey.html](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKey.html)このオペレーションによって、プレーンテキストキーと、 AWS KMS keyで暗号化されたコピーが返ります。これは、*初期のキーマテリアル*と呼ばれます。

   このリクエストの [AWS KMS 暗号化テキスト](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#encrypt_context)には、次のプレーンテキスト形式の値が含まれています。これらのシークレットではない値は、暗号化されたオブジェクトに暗号的にバインドされているため、復号時には同じ暗号化コンテキストが必要です。これらの値を使用して、[AWS CloudTrail ログ](https://docs.aws.amazon.com/kms/latest/developerguide/monitoring-overview.html) AWS KMS で への呼び出しを識別できます。
   + amzn-ddb-env-alg - 暗号化アルゴリズム。デフォルトは AES/256
   + amzn-ddb-sig-alg - 署名アルゴリズム。デフォルトは HmacSHA256/256
   + (オプション) aws-kms-table – *テーブル名*
   + (オプション) *パーティションキー名* – *パーティションキー値* (バイナリ値は Base64 エンコード形式)
   + (オプション) *ソートキー名* – *ソートキー値* (バイナリ値は Base64 エンコード形式)

   Direct KMS プロバイダーは、項目の DynamoDB AWS KMS 暗号化コンテキストから暗号化コンテキストの値を取得します。 [DynamoDB ](concepts.md#encryption-context) DynamoDB 暗号化コンテキストにテーブル名などの値が含まれていない場合、その名前と値のペアは AWS KMS 暗号化コンテキストから省略されます。

1. Direct KMS プロバイダーは、対称暗号化キーおよび署名キーをデータキーから導出します。デフォルトでは、[セキュアハッシュアルゴリズム (SHA) 256](https://en.wikipedia.org/wiki/SHA-2) および [RFC5869 HMAC ベースのキー導出関数](https://tools.ietf.org/html/rfc5869)を使用して、256 ビット AES 対称暗号化キーおよび 256 ビット HMAC-SHA-256 署名キーを導出します。

1. Direct KMS プロバイダーは、項目エンクリプタに出力を返します。

1. 項目エンクリプタは、暗号化キーを使用して、指定された属性を暗号化し、署名キーを使用して署名します。この際、実際のマテリアル記述で指定されたアルゴリズムを使用します。可能な限り早く、メモリよりプレーンテキストキーが削除されます。

### 復号マテリアルを取得する
<a name="direct-kms-get-decryption-materials"></a>

このセクションでは、[項目エンクリプタ](DDBEC-legacy-concepts.md#item-encryptor)より復号マテリアルのリクエストを受け取るときの Direct KMS プロバイダーの入力、出力、処理の詳細について説明します。

**入力** (アプリケーションから)
+ のキー ID AWS KMS key。

  キー ID の値は、キー ID、キー ARN、エイリアス名、または AWS KMS keyのエイリアス ARN にすることができます。キー ID に含まれていない値 (リージョンなど) はすべて、[AWS 名前付きプロファイル](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html#cli-configure-files-using-profiles)で入手できる必要があります。キー ARN により、 AWS KMS で必要なすべての値が提供されます。

**入力** (項目エンクリプタから)
+ [DynamoDB 暗号化コンテキスト](concepts.md#encryption-context)のコピー (マテリアル説明属性の内容を含む)。

**出力** (項目エンクリプタへ)
+ 暗号化キー (プレーンテキスト)
+ 署名キー

**Processing**

1. Direct KMS プロバイダーは、暗号化された項目のマテリアル記述属性から暗号化されたデータキーを取得します。

1. は、指定された AWS KMS key を使用して暗号化されたデータキーを[復号](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKey.html) AWS KMS するよう に要求します。オペレーションでプレーンテキストのキーが返ります。

   このリクエストでは、データキーの生成および暗号化に使用したのと同じ [AWS KMS 暗号化コンテキスト](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#encrypt_context)を使用する必要があります。
   + aws-kms-table – *テーブル名*
   + *パーティションキー名* – *パーティションキー値* (バイナリ値は Base64 エンコード形式)
   + (オプション) *ソートキー名* – *ソートキー値* (バイナリ値は Base64 エンコード形式)
   + amzn-ddb-env-alg - 暗号化アルゴリズム。デフォルトは AES/256
   + amzn-ddb-sig-alg - 署名アルゴリズム。デフォルトは HmacSHA256/256

1. Direct KMS プロバイダーでは、[セキュアハッシュアルゴリズム (SHA) 256](https://en.wikipedia.org/wiki/SHA-2) および [RFC5869 HMAC ベースのキー導出関数](https://tools.ietf.org/html/rfc5869)を使用して、データキーから 256 ビット AES 対称暗号化キーおよび 256 ビット HMAC-SHA-256 署名キーを導出します。

1. Direct KMS プロバイダーは、項目エンクリプタに出力を返します。

1. 項目エンクリプタは、署名キーを使用して項目を検証します。成功すると、暗号化された属性値は対称暗号化キーを使用して復号されます。これらのオペレーションでは、実際のマテリアル記述で指定された暗号化アルゴリズムおよび署名アルゴリズムが使用されます。項目エンクリプタによって、可能な限り早く、メモリよりプレーンテキストキーが削除されます。

# ラップされたマテリアルプロバイダー
<a name="wrapped-provider"></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)」を参照してください。

*ラップされたマテリアルプロバイダー* (ラップされた CMP) では、DynamoDB 暗号化クライアントを使用して任意のソースからラッピングおよび署名キーを使用できます。ラップされた CMP はどの AWS サービスにも依存しません。ただし、クライアントの外部にあるラップキーと署名キーを生成して管理する必要があります。これには、項目を検証および復号するための正しいキーを提供することが含まれます。

ラップされた CMP は、項目ごとに固有の項目暗号化キーを生成します。項目暗号化キーを指定したラップキーでラップし、ラップされた項目暗号化キーを項目の[マテリアル説明属性](DDBEC-legacy-concepts.md#legacy-material-description)に保存します。ラップキーと署名キーを指定するため、ラップキーと署名キーの生成方法と、それらが各項目に固有のものか再利用されたものかを判断します。

ラップされた CMP は、安全な実装であり、暗号化マテリアルを管理できるアプリケーションに適しています。

ラップされた CMP は、DynamoDB 暗号化クライアントがサポートしている複数の[暗号化マテリアルプロバイダー](DDBEC-legacy-concepts.md#concept-material-provider) (CMP) の 1 つです。他の CMP の詳細については、「[暗号マテリアルプロバイダー](crypto-materials-providers.md)」を参照してください。

**サンプルコードについては、以下を参照してください。**
+ Java: [AsymmetricEncryptedItem](https://github.com/aws/aws-dynamodb-encryption-java/blob/master/examples/src/main/java/com/amazonaws/examples/AsymmetricEncryptedItem.java)
+ Python: [wrapped-rsa-encrypted-table](https://github.com/aws/aws-dynamodb-encryption-python/blob/master/examples/src/dynamodb_encryption_sdk_examples/wrapped_rsa_encrypted_table.py)、[wrapped-symmetric-encrypted-table](https://github.com/aws/aws-dynamodb-encryption-python/blob/master/examples/src/dynamodb_encryption_sdk_examples/wrapped_symmetric_encrypted_table.py)

**Topics**
+ [使用方法](#wrapped-cmp-how-to-use)
+ [仕組み](#wrapped-cmp-how-it-works)

## 使用方法
<a name="wrapped-cmp-how-to-use"></a>

ラップされた CMP を作成するには、ラップキー (暗号化に必要)、ラップ解除キー (復号に必要)、および署名キーを指定します。項目を暗号化および復号するときには、キーを指定する必要があります。

ラップキー、ラップ解除キー、および署名キーは、対称キーまたは非対称キーペアにすることができます。

------
#### [ Java ]

```
// This example uses asymmetric wrapping and signing key pairs
final KeyPair wrappingKeys = ...
final KeyPair signingKeys = ...

final WrappedMaterialsProvider cmp = 
    new WrappedMaterialsProvider(wrappingKeys.getPublic(),
                                 wrappingKeys.getPrivate(),
                                 signingKeys);
```

------
#### [ Python ]

```
# This example uses symmetric wrapping and signing keys
wrapping_key = ...
signing_key  = ...

wrapped_cmp = WrappedCryptographicMaterialsProvider(
    wrapping_key=wrapping_key,
    unwrapping_key=wrapping_key,
    signing_key=signing_key
)
```

------

## 仕組み
<a name="wrapped-cmp-how-it-works"></a>

ラップされた CMP は、すべての項目に新しい項目暗号化キーを生成します。次の図に示すように、ラップキー、ラップ解除キー、および署名キーを使用します。

![\[DynamoDB 暗号化クライアントでのラップされたマテリアルプロバイダーの入力、処理、および出力\]](http://docs.aws.amazon.com/ja_jp/database-encryption-sdk/latest/devguide/images/wrappedCMP.png)


### 暗号化マテリアルを取得する
<a name="wrapped-cmp-get-encryption-materials"></a>

このセクションでは、暗号化マテリアルのリクエストを受け取る際のラップされたマテリアルプロバイダー (ラップされた CMP) の入力、出力、処理の詳細について説明します。

**入力** (アプリケーションから)
+ ラップされたキー: [Advanced Encryption Standard](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard) (AES) 対称キー、または [RSA](https://en.wikipedia.org/wiki/RSA_(cryptosystem)) パブリックキー。属性値が暗号化されている場合は必須です。それ以外の場合はオプションであり、無視されます。
+ ラップ解除キー: オプションで無視されます。
+ 署名キー

**入力** (項目エンクリプタから)
+ [DynamoDB 暗号化コンテキスト](concepts.md#encryption-context)

**出力** (項目エンクリプタへ):
+ プレーンテキスト項目暗号化キー
+ 署名キー (変更されません)
+ [実際のマテリアル説明](DDBEC-legacy-concepts.md#legacy-material-description): これらの値は、クライアントが項目に追加する[マテリアル説明属性](DDBEC-legacy-concepts.md#legacy-material-description)に保存されます。
  + `amzn-ddb-env-key`: Base64 でエンコードされたラップされた項目暗号化キー
  + `amzn-ddb-env-alg`: 項目を暗号化するために使用される暗号化アルゴリズム。デフォルトは AES-256-CBC です。
  + `amzn-ddb-wrap-alg`: ラップされた CMP が項目暗号化キーをラップするために使用したラップアルゴリズム。ラッピングキーが AES キーの場合、[RFC 3394](https://tools.ietf.org/html/rfc3394.html) で定義されているように、キーは埋め込みなしの `AES-Keywrap` を使用してラップされます。ラップキーが RSA キーの場合、キーは MGF1 パディング付き RSA OAEP を使用して暗号化されます。

**Processing**

項目を暗号化する際は、ラップキーと署名キーで渡します。ラップ解除キーは、オプションで無視されます。

1. ラップされた CMP は、テーブル項目に固有の対称項目暗号化キーを生成します。

1. 項目暗号化キーをラップするために指定したラップキーを使用します。次に、可能な限り早く、メモリより削除されます。

1. これは、プレーンテキスト項目暗号化キー、指定した署名キー、[実際のマテリアル説明](DDBEC-legacy-concepts.md#legacy-material-description) (ラップされた項目暗号化キー、暗号化およびラップアルゴリズムを含む) を返します。

1. 項目エンクリプタは、プレーンテキスト暗号化キーを使用して項目を暗号化します。項目に署名するために指定した署名キーを使用します。次に、可能な限り早く、メモリよりプレーンテキストキーが削除されます。ラップされた暗号化キー (`amzn-ddb-env-key`) を含む、実際のマテリアル記述のフィールドを項目のマテリアル記述属性にコピーします。

### 復号マテリアルを取得する
<a name="wrapped-cmp-get-decryption-materials"></a>

このセクションでは、復号マテリアルのリクエストを受け取る際のラップされたマテリアルプロバイダー (ラップされた CMP) の入力、出力、処理の詳細について説明します。

**入力** (アプリケーションから)
+ ラップキー: オプションで無視されます。
+ ラップ解除キー: 同じ [Advanced Encryption Standard](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard) (AES) 対称キーまたは [RSA](https://en.wikipedia.org/wiki/RSA_(cryptosystem)) 暗号化に使用された RSA パブリックキーに対応するプライベートキー。属性値が暗号化されている場合は必須です。それ以外の場合はオプションであり、無視されます。
+ 署名キー

**入力** (項目エンクリプタから)
+ [DynamoDB 暗号化コンテキスト](concepts.md#encryption-context)のコピー (マテリアル説明属性の内容を含む)。

**出力** (項目エンクリプタへ)
+ プレーンテキスト項目暗号化キー
+ 署名キー (変更されません)

**Processing**

項目を復号する際は、ラップ解除キーと署名キーで渡します。ラップキーは、オプションで無視されます。

1. ラップされた CMP は、項目のマテリアル記述属性からラップされた項目暗号化キーを取得します。

1. 項目暗号化キーをラップ解除するためにラップ解除キーとアルゴリズムを使用します。

1. それは、項目エンクリプタにプレーンテキスト項目暗号化キー、署名キー、および暗号化および署名アルゴリズムを返します。

1. 項目エンクリプタは、署名キーを使用して項目を検証します。成功すると、項目暗号化キーを使用して項目を復号します。次に、可能な限り早く、メモリよりプレーンテキストキーが削除されます。

# 最新プロバイダー
<a name="most-recent-provider"></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)」を参照してください。

*最新プロバイダー*は、[プロバイダーストア](DDBEC-legacy-concepts.md#provider-store)で機能するように設計された[暗号化マテリアルプロバイダー](DDBEC-legacy-concepts.md#concept-material-provider) (CMP) です。プロバイダーストアから CMP を取得し、CMP から返る暗号化マテリアルを取得します。これは、通常、各 CMP を使用して複数の暗号化マテリアルをリクエストします。ただし、プロバイダーストアの機能を使用して、マテリアルが再利用される範囲を制御し、CMP のローテーション頻度を決定し、最新プロバイダーを変更せずに使用する CMP のタイプを変更することもできます。

**注記**  
最新プロバイダーの `MostRecentProvider` 記号に関連付けられたコードは、プロセスの有効期間の間、暗号化マテリアルをメモリに保存する場合があります。これにより、呼び出し元は、使用する権限がなくなったキーを使用できるようになる可能性があります。  
`MostRecentProvider` 記号は、DynamoDB 暗号化クライアントのサポートされている古いバージョンでは廃止されており、バージョン 2.0.0 から除去されています。これは、`CachingMostRecentProvider` 記号に置き換えられています。詳細については、「[最新プロバイダーの更新](#mrp-versions)」を参照してください。

最新プロバイダーは、プロバイダーストアとその暗号ソースへの呼び出しを最小限に抑える必要のあるアプリケーションや、セキュリティ要件に違反せずに一部の暗号化マテリアルを再利用できるアプリケーションに適しています。たとえば、項目を暗号化または復号する AWS KMS たびに を呼び出すことなく、 [AWS KMS key](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys) [AWS Key Management Service](https://docs.aws.amazon.com/kms/latest/developerguide/) (AWS KMS) の で暗号化マテリアルを保護できます。

選択したプロバイダーストアによって、最新プロバイダーが使用する CMP のタイプと、新しい CMP を取得する頻度が決まります。設計したカスタムプロバイダーストアを含む、最新プロバイダーと互換性のある任意のプロバイダーストアを使用できます。

DynamoDB 暗号化クライアントには、[ラップされたマテリアルプロバイダー](wrapped-provider.md) (ラップされた CMP) を作成して返す *MetaStore* が含まれています。MetaStore は、生成したラップされた CMP の複数のバージョンを内部の DynamoDB テーブルに保存し、DynamoDB 暗号化クライアントの内部インスタンスによるクライアント側の暗号化でそれらを保護します。

任意のタイプの内部 CMP を使用するように MetaStore を設定して、 によって保護された暗号化マテリアルを生成する [Direct KMS プロバイダー](direct-kms-provider.md) AWS KMS key、指定したラッピングキーと署名キーを使用するラップされた CMP、または設計した互換性のあるカスタム CMP など、テーブル内のマテリアルを保護できます。

**サンプルコードについては、以下を参照してください。**
+ Java: [MostRecentEncryptedItem](https://github.com/aws/aws-dynamodb-encryption-java/blob/master/examples/src/main/java/com/amazonaws/examples/MostRecentEncryptedItem.java)
+ Python: [most\$1recent\$1provider\$1encrypted\$1table](https://github.com/aws/aws-dynamodb-encryption-python/blob/master/examples/src/dynamodb_encryption_sdk_examples/most_recent_provider_encrypted_table.py)

**Topics**
+ [使用方法](#mrp-how-to-use-it)
+ [仕組み](#mrp-how-it-works)
+ [最新プロバイダーの更新](#mrp-versions)

## 使用方法
<a name="mrp-how-to-use-it"></a>

最新プロバイダーを作成するには、プロバイダーストアを作成して構成した後、プロバイダーストアを使用する最新プロバイダーを作成する必要があります。

次の例は、MetaStore を使用し、[Direct KMS プロバイダー](direct-kms-provider.md)から暗号化マテリアルを含む内部 DynamoDB テーブルのバージョンを保護する最新プロバイダーを作成する方法を示しています。以下の例では、[`CachingMostRecentProvider`](#mrp-versions) 記号を使用します。

それぞれの最新プロバイダーには、MetaStore テーブル内の CMP、[有効期限](#most-recent-provider-ttl) (TTL) 設定、およびキャッシュが保持できるエントリの数を決定するキャッシュサイズ設定を特定する名前が付けられています。これらの例では、キャッシュサイズを 1000 エントリに設定し、TTL を 60 秒に設定します。

------
#### [ Java ]

```
// Set the name for MetaStore's internal table
final String keyTableName = 'metaStoreTable'

// Set the Region and AWS KMS key
final String region = 'us-west-2'
final String keyArn = 'arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab'

// Set the TTL and cache size
final long ttlInMillis = 60000;
final long cacheSize = 1000;

// Name that identifies the MetaStore's CMPs in the provider store
final String materialName = 'testMRP'

// Create an internal DynamoDB client for the MetaStore
final AmazonDynamoDB ddb = AmazonDynamoDBClientBuilder.standard().withRegion(region).build();

// Create an internal Direct KMS Provider for the MetaStore
final AWSKMS kms = AWSKMSClientBuilder.standard().withRegion(region).build();
final DirectKmsMaterialProvider kmsProv = new DirectKmsMaterialProvider(kms, keyArn);

// Create an item encryptor for the MetaStore,
// including the Direct KMS Provider
final DynamoDBEncryptor keyEncryptor = DynamoDBEncryptor.getInstance(kmsProv);

// Create the MetaStore
final MetaStore metaStore = new MetaStore(ddb, keyTableName, keyEncryptor);

//Create the Most Recent Provider
final CachingMostRecentProvider cmp = new CachingMostRecentProvider(metaStore, materialName, ttlInMillis, cacheSize);
```

------
#### [ Python ]

```
# Designate an AWS KMS key
kms_key_id = 'arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab'

# Set the name for MetaStore's internal table
meta_table_name = 'metaStoreTable'

# Name that identifies the MetaStore's CMPs in the provider store
material_name = 'testMRP'

# Create an internal DynamoDB table resource for the MetaStore
meta_table = boto3.resource('dynamodb').Table(meta_table_name)

# Create an internal Direct KMS Provider for the MetaStore
kms_cmp = AwsKmsCryptographicMaterialsProvider(key_id=kms_key_id)
    
# Create the MetaStore with the Direct KMS Provider
meta_store = MetaStore(
    table=meta_table,
    materials_provider=kms_cmp
)

# Create a Most Recent Provider using the MetaStore
#    Sets the TTL (in seconds) and cache size (# entries)
most_recent_cmp = MostRecentProvider(
    provider_store=meta_store,
    material_name=material_name,
    version_ttl=60.0,
    cache_size=1000
)
```

------

## 仕組み
<a name="mrp-how-it-works"></a>

最新プロバイダーがプロバイダーストアから CMP を取得します。次に、CMP を使用して、暗号化マテリアルを生成し、それを項目エンクリプタに返します。

### 最新プロバイダーについて
<a name="about-mrp"></a>

最新プロバイダーは、[プロバイダーストア](DDBEC-legacy-concepts.md#provider-store)から[暗号化マテリアルプロバイダー](DDBEC-legacy-concepts.md#concept-material-provider) (CMP) を取得します。次に、CMP を使用して、それが返す暗号化マテリアルを生成します。各最新プロバイダーは 1 つのプロバイダーストアに関連付けられていますが、プロバイダーストアは複数のホスト間で複数のプロバイダーに CMP を提供できます。

最新プロバイダーは、任意のプロバイダーストアから互換性のある CMP を使用できます。暗号化または復号マテリアルを CMP に要求し、項目エンクリプタに出力を返します。暗号化オペレーションは実行されません。

最新プロバイダーは、そのプロバイダーストアから CMP を要求するために、使用する既存の CMP のマテリアル名とバージョンを提供します。暗号化マテリアルでは、最新プロバイダーは常に最大 (「最新の」) バージョンをリクエストします。復号マテリアルの場合、次の図に示すように、暗号化マテリアルの作成に使用された CMP のバージョンをリクエストします。

![\[最新プロバイダー\]](http://docs.aws.amazon.com/ja_jp/database-encryption-sdk/latest/devguide/images/most-recent-provider-1.png)


最新プロバイダーは、プロバイダーストアが返す CMP のバージョンをメモリ内のローカル最小使用 (LRU) キャッシュに保存します。キャッシュにより、最新プロバイダーは、すべての項目のプロバイダーストアを呼び出さずに必要な CMP を取得できます。必要に応じてキャッシュをクリアすることができます。

最新プロバイダーは、アプリケーションの特性に基づいて調整できる設定可能な[有効期限 (TTL) 値](#most-recent-provider-ttl)を使用します。

### MetaStore について
<a name="about-metastore"></a>

互換性のあるカスタムプロバイダーストアなどの任意のプロバイダーストアで最新プロバイダーを使用できます。DynamoDB 暗号化クライアントには、設定してカスタマイズできる安全な実装である MetaStore が含まれています。

*MetaStore* は、CMP で必要なラッピングキー、ラップ解除キー、および署名キーで構成された、[ラップされた CMP](wrapped-provider.md) を作成して返す[プロバイダーストア](DDBEC-legacy-concepts.md#provider-store)です。ラップされた CMP は常にすべての項目に対して一意の項目暗号化キーを生成するため、MetaStore は最新プロバイダーにとって安全なオプションです。項目暗号化キーと署名キーを保護するラップキーのみが再利用されます。

次の図は、MetaStore のコンポーネントと、最新プロバイダーとのやり取りの方法を示しています。

![\[MetaStore\]](http://docs.aws.amazon.com/ja_jp/database-encryption-sdk/latest/devguide/images/most-recent-provider-2.png)


MetaStore はラップされた CMP を生成し、内部 DynamoDB テーブルに (暗号化された形式で) 保存します。パーティションキーは、最新プロバイダーマテリアルの名前であり、ソートキーはそのバージョン番号です。テーブル内のマテリアルは、項目エンクリプタや内部[暗号化マテリアルプロバイダー](DDBEC-legacy-concepts.md#concept-material-provider) (CMP) など、内部 DynamoDB 暗号化クライアントによって保護されています。

MetaStore では、[Direct KMS プロバイダー](wrapped-provider.md)、提供する暗号化マテリアルを使用したラップされた CMP、または互換性のあるカスタム CMP など、あらゆるタイプの内部 CMP を使うことができます。MetaStore の内部 CMP が Direct KMS プロバイダーの場合、再利用可能なラッピングおよび署名キーは、[AWS Key Management Service](https://docs.aws.amazon.com/kms/latest/developerguide/) (AWS KMS) 内の [AWS KMS key](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys) で保護されます。MetaStore は、内部テーブルに新しい CMP バージョンを追加するか、内部テーブルから CMP バージョンを取得する AWS KMS たびに を呼び出します。

### 有効期限 (TTL) の値を設定する
<a name="most-recent-provider-ttl"></a>

作成した最新プロバイダーごとに有効期限 (TTL) の値を設定できます。一般に、アプリケーションで実用的な最も低い TTL 値を使用します。

TTL 値の使用は、最新プロバイダーの `CachingMostRecentProvider` 記号で変更されます。

**注記**  
最新プロバイダーの `MostRecentProvider` 記号は、DynamoDB 暗号化クライアントのサポートされている古いバージョンでは廃止されており、バージョン 2.0.0 から除去されています。これは、`CachingMostRecentProvider` 記号に置き換えられています。可能な限り早急にコードを更新することをお勧めします。詳細については、「[最新プロバイダーの更新](#mrp-versions)」を参照してください。

**`CachingMostRecentProvider`**  
`CachingMostRecentProvider` は、以下の 2 つの異なる方法で TTL 値を使用します。  
+ TTL により、最新プロバイダーがプロバイダーストアで新しいバージョンの CMP をチェックする頻度を決定します。新しいバージョンが利用可能な場合、最新プロバイダーはその CMP を置き換え、暗号化マテリアルを更新します。それ以外の場合、現在の CMP と暗号化マテリアルを引き続き使用します。
+ TTL により、キャッシュ内の CMP を使用できる期間を決定します。キャッシュされた CMP を暗号化に使用する前に、最新プロバイダーはキャッシュ内の時間を評価します。CMP キャッシュ時間が TTL を超えると、CMP はキャッシュから削除され、最新プロバイダーはプロバイダストアから新しい最新バージョン CMP を取得します。

**`MostRecentProvider`**  
`MostRecentProvider` では、TTL により、最新プロバイダーがプロバイダーストアで新しいバージョンの CMP をチェックする頻度が決定されます。新しいバージョンが利用可能な場合、最新プロバイダーはその CMP を置き換え、暗号化マテリアルを更新します。それ以外の場合、現在の CMP と暗号化マテリアルを引き続き使用します。

TTL では、新しい CMP バージョンが作成される頻度は決定されません。新しい CMP バージョンを作成するには、[暗号化マテリアルをローテーション](#most-recent-provider-rotate)します。

理想的な TTL 値は、アプリケーションとそのレイテンシー、および可用性の目標によって異なります。TTL を低くすると、暗号化マテリアルがメモリに格納される時間が短縮され、セキュリティプロファイルが向上します。また、TTL が低いほど、重要な情報がより頻繁に更新されます。例えば、内部 CMP が [Direct KMS プロバイダー](direct-kms-provider.md)である場合、呼び出し元が AWS KMS keyを使用する権限をまだ持っているかを、より頻繁に検証します。

ただし、TTL が低すぎると、プロバイダーストアへの頻繁な呼び出しによってコストが増加し、プロバイダーストアがアプリケーションや、サービスアカウントを共有する他のアプリケーションからのリクエストをスロットリングする可能性があります。また、暗号化マテリアルをローテーションする速度で TTL を調整することでメリットが得られる場合があります。

テスト中に、お使いのアプリケーションと、セキュリティおよびパフォーマンス標準に適した設定が見つかるまで、さまざまなワークロードで TTL とキャッシュサイズを変更します。

### 暗号化マテリアルの回転
<a name="most-recent-provider-rotate"></a>

最新プロバイダーで暗号化マテリアルが必要な場合、最新プロバイダーは必ず、認識している最新バージョンの CMP を使用します。新しいバージョンをチェックする頻度は、最新プロバイダーを構成するときに設定した[有効期限](#most-recent-provider-ttl) (TTL) 値によって決定されます。

TTL が期限切れになると、最新プロバイダーはプロバイダーストアで新しいバージョンの CMP をチェックします。新しいバージョンを使用できる場合、最新プロバイダーはそれを取得し、キャッシュ内の CMP を置き換えます。プロバイダーストアに新しいバージョンがあることが検出されるまで、この CMP とその暗号化マテリアルが使用されます。

最新プロバイダーの新しいバージョンの CMP を作成するようにプロバイダーストアに指示するには、プロバイダーストアの新規プロバイダーの作成オペレーション作を、最新プロバイダーのマテリアル名で呼び出します。プロバイダーストアは新しい CMP を作成し、暗号化されたコピーをより大きなバージョン番号で内部ストレージに保存します。(CMP を返しますが、破棄することもできます。) その結果、次に最新プロバイダーがプロバイダーストアにその CMP の最大バージョン番号を問い合わせるときに、最新プロバイダーは新しいより大きなバージョン番号を取得し、それをストアに対する後続のリクエストで使用して、CMP の新しいバージョンが作成されたかどうかを確認します。

時間、処理された項目または属性の数、またはアプリケーションに合ったその他のメトリクスに基づいて、新しいプロバイダー作成コールをスケジュールできます。

### 暗号化マテリアルを取得する
<a name="most-recent-provider-encrypt"></a>

最新プロバイダーは、この図に示す次のプロセスを使用して、項目エンクリプタに返す暗号化マテリアルを取得します。出力は、プロバイダーストアが返す CMP のタイプによって異なります。最新プロバイダーは、DynamoDB 暗号化クライアントに含まれる MetaStore などの互換性のある任意のプロバイダーストアを使用できます。

![\[DynamoDB 暗号化クライアントでの最新プロバイダーの入力、処理、および出力\]](http://docs.aws.amazon.com/ja_jp/database-encryption-sdk/latest/devguide/images/most-recent-provider-provider-store.png)


[`CachingMostRecentProvider`記号](#mrp-versions)を使用して最新プロバイダーを作成するときに、プロバイダーストア、最新プロバイダーの名前、および[有効期限](#most-recent-provider-ttl) (TTL) 値を指定します。オプションで、キャッシュ内に存在できる暗号化マテリアルの最大数を決定するキャッシュサイズを指定することもできます。

項目エンクリプタが最新プロバイダーに暗号化マテリアルを要求すると、最新プロバイダーは、その CMP の最新バージョンのキャッシュの検索を開始します。
+ キャッシュ内で最新バージョンの CMP を検出し、CMP が TTL 値を超過していない場合、最新プロバイダーは CMP を使用して暗号化マテリアルを生成します。次に、暗号化マテリアルを項目エンクリプタに返します。このオペレーションでは、プロバイダーストアへの呼び出しは必要ありません。
+ CMP の最新バージョンがキャッシュ内に存在しない場合、またはキャッシュ内に存在していても TTL 値を超過している場合、最新プロバイダーはそのプロバイダーストアから CMP をリクエストします。リクエストには、最新プロバイダーのマテリアル名と、既知の最大のバージョン番号が含まれています。

  1. プロバイダーストアは、永続的ストレージから CMP を返します。プロバイダーストアが MetaStore の場合、最新プロバイダーのマテリアル名をパーティションキーとして使用し、バージョン番号をソートキーとして使用して、内部の DynamoDB テーブルから暗号化済みのラップされた CMP を取得します。MetaStore は、内部項目エンクリプタと内部 CMP を使用して、ラップされた CMP を復号します。次に、プレーンテキスト CMP を最新プロバイダーに返します。内部 CMP が [Direct KMS Provider](direct-kms-provider.md) の場合、このステップには [AWS Key Management Service](https://docs.aws.amazon.com/kms/latest/developerguide/) (AWS KMS) コールが含まれます。

  1. CMP は、`amzn-ddb-meta-id`フィールドを[実際のマテリアル説明](DDBEC-legacy-concepts.md#legacy-material-description)に追加します。その値は、内部テーブルの CMP のマテリアル名とバージョンです。プロバイダーストアは CMP を最新プロバイダーに返します。

  1. 最新プロバイダーは CMP をメモリにキャッシュします。

  1. 最新プロバイダーは CMP を使用して暗号化マテリアルを生成します。次に、暗号化マテリアルを項目エンクリプタに返します。

### 復号マテリアルを取得する
<a name="most-recent-provider-decrypt"></a>

項目エンクリプタが最新プロバイダーに復号マテリアルを要求すると、最新プロバイダーは以下のプロセスを使用して、それらを取得し返します。

1. 最新プロバイダーは、項目を暗号化するために使用された暗号化マテリアルのバージョン番号をプロバイダーストアに問い合わせます。項目の[マテリアル説明属性](DDBEC-legacy-concepts.md#legacy-material-description)から実際のマテリアル説明を渡します。

1. プロバイダーストアは、実際のマテリアル説明の `amzn-ddb-meta-id` フィールドから暗号化 CMP バージョン番号を取得し、最新プロバイダーに返します。

1. 最新プロバイダーは、項目の暗号化と署名に使用された CMP のバージョンをキャッシュ内で検索します。
+ CMP の一致するバージョンがキャッシュにあり、かつ、CMP が[有効期限 (TTL) 値](#most-recent-provider-ttl)を超過していないことがわかった場合、最新プロバイダーは CMP を使用して復号マテリアルを生成します。次に、復号マテリアルを項目エンクリプタに返します。このオペレーションでは、プロバイダーストアまたは他の CMP への呼び出しは必要ありません。
+ CMP の一致するバージョンがキャッシュ内に存在しない場合、またはキャッシュされた AWS KMS key が TTL 値を超過している場合、最新プロバイダーはそのプロバイダーストアから CMP をリクエストします。リクエストには、マテリアル名および暗号化 CMP バージョン番号が送信されます。

  1. プロバイダーストアは、最新プロバイダー名をパーティションキーとして使用し、バージョン番号をソートキーとして使用して、CMP の永続的ストレージを検索します。
     + 名前とバージョン番号が永続的ストレージにない場合、プロバイダーストアは例外をスローします。CMP を生成するためにプロバイダーストアを使用した場合、意図的に削除されていない限り、CMP は永続的ストレージに保存する必要があります。
     + 一致する名前とバージョン番号を持つ CMP がプロバイダーストアの永続的ストレージにある場合、プロバイダーストアは指定された CMP を最新プロバイダーに返します。

       プロバイダーストアが MetaStore の場合、その DynamoDB テーブルから暗号化済みの CMP を取得します。次に、内部 CMP の暗号化マテリアルを使用して、CMP を最新プロバイダーに返す前に暗号化された CMP を復号します。内部 CMP が [Direct KMS Provider](direct-kms-provider.md) の場合、このステップには [AWS Key Management Service](https://docs.aws.amazon.com/kms/latest/developerguide/) (AWS KMS) コールが含まれます。

  1. 最新プロバイダーは CMP をメモリにキャッシュします。

  1. 最新プロバイダーは CMP を使用して復号マテリアルを生成します。次に、復号マテリアルを項目エンクリプタに返します。

## 最新プロバイダーの更新
<a name="mrp-versions"></a>

最新プロバイダーの記号が `MostRecentProvider` から `CachingMostRecentProvider` に変更されています。

**注記**  
最新プロバイダーを表す `MostRecentProvider` 記号は、両方の言語実装で、Java 用 DynamoDB 暗号化クライアントバージョン 1.15、および Python 用 DynamoDB 暗号化クライアントバージョン 1.3 では廃止され、DynamoDB 暗号化クライアントバージョン 2.0.0 では除去されています。代わりに、`CachingMostRecentProvider` を使用してください。

`CachingMostRecentProvider` では、以下の変更が実装されます。
+ `CachingMostRecentProvider` は、メモリ内の時間が、設定された[有効期限 (TTL) 値](#most-recent-provider-ttl)を超過すると、メモリから暗号化マテリアルを定期的に除去します。

  `MostRecentProvider` は、プロセスの有効期間の間、メモリに暗号化マテリアルを保存する場合があります。その結果、最新プロバイダーは認可の変更を認識しない可能性があります。暗号化キーを使用するための呼び出し元のアクセス許可が取り消された後に、暗号化キーを使用する場合があります。

  この新しいバージョンにアップデートできない場合、キャッシュで `clear()` メソッドを定期的に呼び出すことで同様の効果を得られます。このメソッドは、キャッシュの内容を手動でフラッシュし、最新プロバイダーが新しい CMP と新しい暗号化マテリアルを要求するように求めます。
+ また、`CachingMostRecentProvider` にキャッシュサイズの設定を含めて、キャッシュに対するより詳細な制御を行うこともできます。

`CachingMostRecentProvider` を更新するには、コード内の記号名を変更する必要があります。その他の点ではすべて、`CachingMostRecentProvider` には `MostRecentProvider` との完全な下位互換性があります。テーブル項目を再暗号化する必要はありません。

ただし、`CachingMostRecentProvider` による、基盤となる主要インフラストラクチャへの呼び出しが増えます。有効期限 (TTL) の各間隔で、プロバイダーストアが少なくとも 1 回呼び出されます。多数のアクティブな CMP を持つアプリケーション（頻繁なローテーションによる）、または大規模なフリートを持つアプリケーションは、この変更の影響を受ける可能性が最も高くなります。

更新したコードをリリースする前に、徹底的にテストして、より頻繁な呼び出しによってアプリケーションが損なわれたり、 AWS Key Management Service (AWS KMS) や Amazon DynamoDB など、プロバイダーが依存するサービスによってスロットリングが発生したりしないことを確認します。パフォーマンスの問題を軽減するために、確認したパフォーマンス特性に基づいて、`CachingMostRecentProvider` のキャッシュサイズや有効期限 (TTL) を調整してください。ガイダンスについては、「[有効期限 (TTL) の値を設定する](#most-recent-provider-ttl)」を参照してください。

# 静的マテリアルプロバイダー
<a name="static-provider"></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)」を参照してください。

*静的マテリアルプロバイダー* (静的 CMP) は、テスト、概念実証デモ、および従来の互換性を目的とした、非常にシンプルな[暗号化マテリアルプロバイダー](DDBEC-legacy-concepts.md#concept-material-provider) (CMP) です。

静的 CMP を使用してテーブル項目を暗号化するには、[Advanced Encryption Standard](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard) (AES) 対称暗号化キーと署名キーまたはキーペアを指定します。暗号化された項目を復号するために同じキーを指定する必要があります。静的 CMP は暗号化オペレーションを実行しません。代わりに、項目エンクリプタに指定した暗号化キーをそのまま渡します。項目エンクリプタは、暗号化キーの直下の項目を暗号化します。次に、署名キーを直接使用して署名します。

静的 CMP は一意の暗号化マテリアルを生成しないため、処理するすべてのテーブル項目は同じ暗号化キーで暗号化され、同じ署名キーで署名されます。同じキーを使用して多数の項目の属性値を暗号化するか、同じキーまたはキーペアを使用してすべての項目に署名すると、キーの暗号化の制限を超える危険性があります。

**注記**  
Java ライブラリ内の[非対称静的プロバイダー](https://aws.github.io/aws-dynamodb-encryption-java/com/amazonaws/services/dynamodbv2/datamodeling/encryption/providers/AsymmetricStaticProvider.html)は静的プロバイダーではありません。これは、[ラップされた CMP](wrapped-provider.md) の代替コンストラクタを指定するだけです。本稼働環境での使用は安全ですが、できるだけラップされた CMP を直接使用する必要があります。

静的 CMP は、DynamoDB 暗号化クライアントがサポートしている複数の[暗号化マテリアルプロバイダー](DDBEC-legacy-concepts.md#concept-material-provider) (CMP) の 1 つです。他の CMP の詳細については、「[暗号マテリアルプロバイダー](crypto-materials-providers.md)」を参照してください。

**サンプルコードについては、以下を参照してください。**
+ Java: [SymmetricEncryptedItem](https://github.com/aws/aws-dynamodb-encryption-java/blob/master/examples/src/main/java/com/amazonaws/examples/SymmetricEncryptedItem.java)

**Topics**
+ [使用方法](#static-cmp-how-to-use)
+ [仕組み](#static-cmp-how-it-works)

## 使用方法
<a name="static-cmp-how-to-use"></a>

静的なプロバイダーを作成するには、暗号化キーやキーペアおよび署名キーやキーペアを指定します。テーブル項目を暗号化および復号するには、キーマテリアルを指定する必要があります。

------
#### [ Java ]

```
// To encrypt
SecretKey cek = ...;        // Encryption key
SecretKey macKey =  ...;    // Signing key
EncryptionMaterialsProvider provider = new SymmetricStaticProvider(cek, macKey);

// To decrypt
SecretKey cek = ...;        // Encryption key
SecretKey macKey =  ...;    // Verification key
EncryptionMaterialsProvider provider = new SymmetricStaticProvider(cek, macKey);
```

------
#### [ Python ]

```
# You can provide encryption materials, decryption materials, or both
encrypt_keys = EncryptionMaterials(
    encryption_key = ...,
    signing_key = ...
)

decrypt_keys = DecryptionMaterials(
    decryption_key = ...,
    verification_key = ...
)

static_cmp = StaticCryptographicMaterialsProvider(
    encryption_materials=encrypt_keys
    decryption_materials=decrypt_keys
)
```

------

## 仕組み
<a name="static-cmp-how-it-works"></a>

静的プロバイダーは、指定した暗号化キーと署名キーを項目エンクリプタに渡します。ここで、これらのアイテムは、テーブル項目の暗号化と署名に直接使用されます。各項目に異なるキーを指定しない限り、すべての項目で同じキーが使用されます。

![\[DynamoDB 暗号化クライアントでの静的マテリアルプロバイダーの入力、処理、および出力\]](http://docs.aws.amazon.com/ja_jp/database-encryption-sdk/latest/devguide/images/staticCMP.png)


### 暗号化マテリアルを取得する
<a name="static-cmp-get-encryption-materials"></a>

このセクションでは、暗号化マテリアルのリクエストを受け取る際の静的マテリアルプロバイダー (静的 CMP) の入力、出力、処理の詳細について説明します。

**入力** (アプリケーションから)
+ 暗号化キー - これは、[Advanced Encryption Standard (AES) キー](https://tools.ietf.org/html/rfc3394.html)などの対称キーである必要があります。
+ 署名キー - これは、対称キーまたは非対称キーペアです。

**入力** (項目エンクリプタから)
+ [DynamoDB 暗号化コンテキスト](concepts.md#encryption-context)

**出力** (項目エンクリプタへ)
+ 入力として渡される暗号化キー。
+ 入力として渡される署名キー。
+ 実際のマテリアル説明: [リクエストされたマテリアル説明](DDBEC-legacy-concepts.md#legacy-material-description)。存在する場合は、変更されません。

### 復号マテリアルを取得する
<a name="static-cmp-get-decryption-materials"></a>

このセクションでは、復号マテリアルのリクエストを受け取る際の静的マテリアルプロバイダー (静的 CMP) の入力、出力、処理の詳細について説明します。

暗号化マテリアルの取得と、復号マテリアルの取得のための異なるメソッドが含まれていますが、動作は同じです。

**入力** (アプリケーションから)
+ 暗号化キー - これは、[Advanced Encryption Standard (AES) キー](https://tools.ietf.org/html/rfc3394.html)などの対称キーである必要があります。
+ 署名キー - これは、対称キーまたは非対称キーペアです。

**入力** (項目エンクリプタから)
+ [DynamoDB 暗号化コンテキスト](concepts.md#encryption-context) (使用しません)

**出力** (項目エンクリプタへ)
+ 入力として渡される暗号化キー。
+ 入力として渡される署名キー。

# Amazon DynamoDB Encryption Client で利用可能なプログラミング言語
<a name="programming-languages"></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 では、以下のプログラミング言語を使用できます。言語固有のライブラリはさまざまですが、結果として得られる実装は相互運用ができます。たとえば、Java クライアントで項目を暗号化 (および署名) し、Python クライアントで項目を復号することができます。

詳細については、該当するトピックを参照してください。

**Topics**
+ [Java](java.md)
+ [Python](python.md)

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

# Python 用 DynamoDB 暗号化クライアント
<a name="python"></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)」を参照してください。

このトピックでは、Python 用 DynamoDB 暗号化クライアントをインストールして使用する方法について説明します。このコードは、GitHub の [aws-dynamodb-encryption-python](https://github.com/aws/aws-dynamodb-encryption-python/) リポジトリにあり、開始するのに役立つ完全でテスト済みの[サンプルコード](https://github.com/aws/aws-dynamodb-encryption-python/tree/master/examples)が含まれています。

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

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

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

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

**Python のサポートされているバージョン**  
Amazon DynamoDB Encryption Client for Python バージョン 3.3.0 以降では、Python 3.8 以降が必要です。Python をダウンロードするには、「[Python のダウンロード](https://www.python.org/downloads/)」を参照してください。  
Amazon DynamoDB Encryption Client for Python の以前のバージョンでは Python 2.7 および Python 3.4 以降がサポートされていますが、最新バージョンの DynamoDB 暗号化クライアントを使用することをお勧めします。

**Python 用 pip インストールツール**  
Python 3.6 以降には **pip** が含まれていますが、アップグレードすることもできます。pip のアップグレードまたはインストールの詳細については、**pip** ドキュメント内の[インストール](https://pip.pypa.io/en/latest/installation/)を参照してください。

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

以下の例に示すように、**pip** を使用して Amazon DynamoDB Encryption Client for Python をインストールします。

**最新バージョンをインストールするには**  

```
pip install dynamodb-encryption-sdk
```

**pip** を使用してパッケージをインストールおよびアップグレードする方法の詳細については、「[パッケージのインストール](https://packaging.python.org/tutorials/installing-packages/)」を参照してください。

DynamoDB 暗号化クライアントでは、すべてのプラットフォームで [cryptography ライブラリ](https://cryptography.io/en/latest/)が必要です。**pip** のすべてのバージョンでは、Windows に **cryptography** ライブラリがインストールされて構築されます。**pip** 8.1 以降では、Linux に **cryptography** がインストールされて構築されます。以前のバージョンの **pip** を使用していて、Linux 環境に**暗号**ライブラリを構築するために必要なツールがない場合は、それらをインストールする必要があります。詳細については、「[Building cryptography on Linux](https://cryptography.io/en/latest/installation/#building-cryptography-on-linux)」を参照してください。

DynamoDB 暗号化クライアントの最新開発バージョンは、GitHub の [aws-dynamodb-encryption-python](https://github.com/aws/aws-dynamodb-encryption-python/) リポジトリから取得できます。

DynamoDB 暗号化クライアントをインストールしたら、このガイドの Python コードの例を見ながら開始します。

# Python 用 Amazon DynamoDB 暗号化クライアントの使用方法
<a name="python-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)」を参照してください。

このトピックでは、Python 用 Amazon DynamoDB 暗号化クライアントの機能の一部について説明します。他のプログラミング言語には実装されていない機能も含まれます。これらの機能は、最も安全な方法で DynamoDB 暗号化クライアントを簡単に使用できるように設計されています。通常とは異なるユースケースを除き、この方法を使用することをお勧めします。

DynamoDB 暗号化クライアントを使用したプログラミングの詳細については、このガイドの [Python の例](python-examples.md)、GitHub の aws-dynamodb-encryption-python リポジトリにある[例](https://github.com/aws/aws-dynamodb-encryption-python/tree/master/examples)、および DynamoDB 暗号化クライアント用の [Python ドキュメント](https://aws-dynamodb-encryption-python.readthedocs.io/en/latest/)を参照してください。

**Topics**
+ [クライアントのヘルパークラス](#python-helpers)
+ [TableInfo クラス](#table-info)
+ [Python の属性アクション](#python-attribute-actions)

## クライアントのヘルパークラス
<a name="python-helpers"></a>

Python 用 DynamoDB 暗号化クライアントには、DynamoDB の Boto 3 クラスをミラーリングする複数のクライアントヘルパークラスが含まれています。これらのヘルパークラスでは、次のように、暗号化の追加、既存の DynamoDB アプリケーションへの署名、一般的な問題の回避を簡単に行うことができます。
+ 項目のプライマリキーを暗号化できないように、プライマリキーの上書きアクションを [AttributeActions](#python-attribute-actions) オブジェクトを追加するか、`AttributeActions` オブジェクトを使用してプライマリキーを暗号化するようにクライアントに明示的に指示している場合は例外をスローします。`AttributeActions` オブジェクトのデフォルトアクションが `DO_NOTHING` の場合、クライアントのヘルパークラスではプライマリキーのアクションが使用されます。それ以外の場合は、`SIGN_ONLY` を使用します。
+ [TableInfo オブジェクト](#python-helpers)を作成し、DynamoDB への呼び出しに基づいて [DynamoDB 暗号化コンテキスト](concepts.md#encryption-context)にデータを入力します。これにより、DynamoDB 暗号化コンテキストの精度が確保され、クライアントはプライマリキーを識別できるようになります。
+ DynamoDB テーブルが読み書きされるときにテーブル項目を透過的に暗号化および復号するメソッド (`put_item` や `get_item` など) をサポートしています。ただし、`update_item` メソッドはサポートされていません。

クライアントのヘルパークラスを使用します。低レベルの[項目エンクリプタ](DDBEC-legacy-concepts.md#item-encryptor)を使用して直接やり取りする必要はありません。項目エンクリプタで高度オプションを設定する必要がある場合を除き、これらのクラスを使用します。

クライアントのヘルパークラスには、以下のものが含まれます。
+ [EncryptedTable](https://aws-dynamodb-encryption-python.readthedocs.io/en/latest/lib/encrypted/table.html#module-dynamodb_encryption_sdk.encrypted.table): 1 つのテーブルを同時に処理するために DynamoDB で[テーブル](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb.html#table)リソースを使用するアプリケーション用。
+ [EncryptedResource](https://aws-dynamodb-encryption-python.readthedocs.io/en/latest/lib/encrypted/resource.html): バッチ処理用に DynamoDB で[サービスリソース](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb.html#service-resource)クラスを使用するアプリケーション用。
+ [EncryptedClient](https://aws-dynamodb-encryption-python.readthedocs.io/en/latest/lib/encrypted/client.html): DynamoDB で[低レベルクライアント](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb.html#client)を使用するアプリケーション用。

クライアントのヘルパークラスを使用するには、ターゲットテーブルの DynamoDB [DescribeTable](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DescribeTable.html) オペレーションを呼び出すアクセス許可が発信者に必要です。

## TableInfo クラス
<a name="table-info"></a>

[TableInfo](https://aws-dynamodb-encryption-python.readthedocs.io/en/latest/lib/tools/structures.html#dynamodb_encryption_sdk.structures.TableInfo) クラスは、DynamoDB テーブルを表すヘルパークラスです。プライマリキーとセカンダリインデックスのフィールドを使用します。これにより、テーブルに関する正確なリアルタイム情報を簡単に取得できます。

[クライアントのヘルパークラス](#python-helpers)を使用している場合は、`TableInfo` オブジェクトが作成、使用されます。それ以外の場合、オブジェクトを明示的に作成できます。例については、[項目エンクリプタを使用する](python-examples.md#python-example-item-encryptor)を参照してください。

`TableInfo` オブジェクトで `refresh_indexed_attributes` メソッドを呼び出すと、DynamoDB [DescribeTable](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DescribeTable.html) オペレーションを呼び出して、オブジェクトのプロパティ値が入力されます。テーブルのクエリは、ハードコーディングのインデックス名よりも信頼性がはるかに高まります。`TableInfo` クラスには、[DynamoDB 暗号化コンテキスト](concepts.md#encryption-context)に必要な値を提供する `encryption_context_values` プロパティも含まれます。

`refresh_indexed_attributes` メソッドを使用するには、ターゲットテーブルの DynamoDB [DescribeTable](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DescribeTable.html) オペレーションを呼び出すアクセス許可が発信者に必要です。

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

[属性アクション](DDBEC-legacy-concepts.md#legacy-attribute-actions)は、項目の各属性に対して実行するアクションを項目エンクリプタに指示します。属性アクションを Python で指定するには、デフォルトアクションで `AttributeActions` オブジェクトと、特定の属性の例外を作成します。有効な値は、列挙型の `CryptoAction` で定義されています。

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

```
DO_NOTHING = 0
SIGN_ONLY = 1
ENCRYPT_AND_SIGN = 2
```

たとえば、この `AttributeActions` オブジェクトは、すべての属性のデフォルトとして `ENCRYPT_AND_SIGN` を確立し、`ISBN` 属性および `PublicationYear` 属性の例外を指定します。

```
actions = AttributeActions(
    default_action=CryptoAction.ENCRYPT_AND_SIGN,
    attribute_actions={
        'ISBN': CryptoAction.DO_NOTHING,
        'PublicationYear': CryptoAction.SIGN_ONLY
    }
)
```

[クライアントのヘルパークラス](#python-helpers)を使用している場合は、プライマリキー属性の属性アクションを指定する必要はありません。クライアントのヘルパークラスを使用して、プライマリキーを暗号化することはできません。

クライアントのヘルパークラスを使用しておらず、デフォルトアクションが `ENCRYPT_AND_SIGN` の場合は、プライマリキーのアクションを指定する必要があります。プライマリキーに推奨されているアクションは `SIGN_ONLY` です。簡単に行うには、`set_index_keys` メソッドを使用します。このメソッドでは、プライマリキーに SIGN\$1ONLY、デフォルトアクションの場合には DO\$1NOTHING が使用されます。

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

```
actions = AttributeActions(
    default_action=CryptoAction.ENCRYPT_AND_SIGN,
)
actions.set_index_keys(*table_info.protected_index_keys())
```

# Python 用 DynamoDB 暗号化クライアントのサンプルコード
<a name="python-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)」を参照してください。

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

**Topics**
+ [EncryptedTable クライアントヘルパークラスを使用する](#python-example-table)
+ [項目エンクリプタを使用する](#python-example-item-encryptor)

## EncryptedTable クライアントヘルパークラスを使用する
<a name="python-example-table"></a>

以下の例は、`EncryptedTable` [クライアントヘルパークラス](python-using.md#python-helpers)で [Direct KMS プロバイダー](direct-kms-provider.md)を使用する方法を示しています。この例では、次の [項目エンクリプタを使用する](#python-example-item-encryptor) の例と同じ[暗号化マテリアルプロバイダー](DDBEC-legacy-concepts.md#concept-material-provider)を使用しています。ただし、低レベルの[項目エンクリプタ](DDBEC-legacy-concepts.md#item-encryptor)と直接やり取りするのではなく、`EncryptedTable` クラスを使用します。

これらの例を比較することで、クライアントのヘルパークラスが行う作業を確認できます。この処理では、[DynamoDB 暗号化コンテキスト](concepts.md#encryption-context)を作成します。また、プライマリキー属性が常に署名されているが暗号化されていないことを確認します。暗号化コンテキストを作成し、プライマリキーを検出するには、クライアントのヘルパークラスで DynamoDB [DescribeTable](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DescribeTable.html) オペレーションを呼び出します。このコードを実行するには、このオペレーションを呼び出すアクセス許可が必要です。

**完全なコードサンプルの参照**: [aws\$1kms\$1encrypted\$1table.py](https://github.com/aws/aws-dynamodb-encryption-python/blob/master/examples/src/dynamodb_encryption_sdk_examples/aws_kms_encrypted_table.py)

ステップ 1: テーブルを作成する  
開始するには、テーブル名を指定して、標準の DynamoDB テーブルのインスタンスを作成します。  

```
table_name='test-table'
table = boto3.resource('dynamodb').Table(table_name)
```

ステップ 2: 暗号化マテリアルプロバイダーを作成する  
選択した[暗号化マテリアルプロバイダー](crypto-materials-providers.md) (CMP) のインスタンスを作成します。  
この例では、[Direct KMS プロバイダー](direct-kms-provider.md)を使用していますが、互換性のある CMP を使用することもできます。Direct KMS プロバイダーを作成するには、[AWS KMS key](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys) を指定します。この例では、 の Amazon リソースネーム (ARN) を使用しますが AWS KMS key、任意の有効なキー識別子を使用できます。  

```
kms_key_id='arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab'
kms_cmp = AwsKmsCryptographicMaterialsProvider(key_id=kms_key_id)
```

ステップ 3: 属性アクションオブジェクトを作成する  
[属性アクション](DDBEC-legacy-concepts.md#legacy-attribute-actions)は、項目の各属性に対して実行するアクションを項目エンクリプタに指示します。この例の `AttributeActions` オブジェクトは、無視される `test` 属性を除くすべての項目を暗号化し、署名します。  
クライアントのヘルパークラスを使用する場合は、プライマリキー属性の属性アクションを指定しないでください。`EncryptedTable` クラスでは、プライマリキー属性に署名しますが、暗号化しません。  

```
actions = AttributeActions(
    default_action=CryptoAction.ENCRYPT_AND_SIGN,
    attribute_actions={'test': CryptoAction.DO_NOTHING}
)
```

ステップ 4: 暗号化されたテーブルを作成する  
標準テーブル、Direct KMS プロバイダー、属性アクションを使用して、暗号化されたテーブルを作成します。このステップで設定を完了します。  

```
encrypted_table = EncryptedTable(
    table=table,
    materials_provider=kms_cmp,
    attribute_actions=actions
)
```

ステップ 5: テーブルにプレーンテキスト項目を入力する  
`encrypted_table` で `put_item` メソッドを呼び出すと、テーブル項目は透過的に暗号化されて署名された後、DynamoDB テーブルに追加されます。  
まず、テーブル項目を定義します。  

```
plaintext_item = {
    'partition_attribute': 'value1',
    'sort_attribute': 55
    'example': 'data',
    'numbers': 99,
    'binary': Binary(b'\x00\x01\x02'),
    'test': 'test-value'
}
```
次に、テーブルにデータを入力します。  

```
encrypted_table.put_item(Item=plaintext_item)
```

DynamoDB テーブルから暗号化形式で項目を取得するには、`table` オブジェクトに対して `get_item` メソッドを呼び出します。復号された項目を取得するには、`get_item` オブジェクトの `encrypted_table` メソッドを呼び出します。

## 項目エンクリプタを使用する
<a name="python-example-item-encryptor"></a>

この例は、テーブル項目を暗号化するときに、項目エンクリプタと自動的にやり取りする[クライアントヘルパークラス](DDBEC-legacy-concepts.md#item-encryptor)を使用する代わりに、DynamoDB 暗号化クライアントで[項目エンクリプタ](python-using.md#python-helpers)と直接やり取りする方法を示しています。

この方法を使用するときは、DynamoDB 暗号化コンテキストと設定オブジェクト (`CryptoConfig`) を手動で作成します。また、1 つの呼び出しで項目を暗号化し、別の呼び出しで DynamoDB テーブルにその項目を入力します。これにより、`put_item` 呼び出しのカスタマイズや、DynamoDB 暗号化クライアントを使用した構造化データの暗号化および署名を行うことができます。このデータが DynamoDB に送信されることはありません。

この例では、[Direct KMS プロバイダー](direct-kms-provider.md)を使用していますが、互換性のある CMP を使用することもできます。

**完全なコードサンプルの参照**: [aws\$1kms\$1encrypted\$1item.py](https://github.com/aws/aws-dynamodb-encryption-python/blob/master/examples/src/dynamodb_encryption_sdk_examples/aws_kms_encrypted_item.py)

ステップ 1: テーブルを作成する  
開始するには、テーブル名を指定して、標準の DynamoDB テーブルリソースのインスタンスを作成します。  

```
table_name='test-table'
table = boto3.resource('dynamodb').Table(table_name)
```

ステップ 2: 暗号化マテリアルプロバイダーを作成する  
選択した[暗号化マテリアルプロバイダー](crypto-materials-providers.md) (CMP) のインスタンスを作成します。  
この例では、[Direct KMS プロバイダー](direct-kms-provider.md)を使用していますが、互換性のある CMP を使用することもできます。Direct KMS プロバイダーを作成するには、[AWS KMS key](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys) を指定します。この例では、 の Amazon リソースネーム (ARN) を使用しますが AWS KMS key、任意の有効なキー識別子を使用できます。  

```
kms_key_id='arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab'
kms_cmp = AwsKmsCryptographicMaterialsProvider(key_id=kms_key_id)
```

ステップ 3: TableInfo ヘルパークラスを使用する  
DynamoDB からテーブルに関する情報を取得するには、[TableInfo](python-using.md#python-helpers) ヘルパークラスのインスタンスを作成します。項目エンクリプタで直接操作する場合は、`TableInfo` インスタンスを作成してそのメソッドを呼び出す必要があります。[クライアントのヘルパークラス](python-using.md#python-helpers)を使用してこの操作を行うことができます。  
`TableInfo` の `refresh_indexed_attributes` メソッドでは、[DescribeTable](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DescribeTable.html) DynamoDB オペレーションを使用して、テーブルに関するリアルタイムで正確な情報を取得します。この情報には、プライマリキーと、ローカルおよびグローバルセカンダリインデックスが含まれます。`DescribeTable` を呼び出すアクセス許可が発信者に必要です。  

```
table_info = TableInfo(name=table_name)
table_info.refresh_indexed_attributes(table.meta.client)
```

ステップ 4: DynamoDB 暗号化コンテキストを作成する  
[DynamoDB 暗号化コンテキスト](concepts.md#encryption-context)には、テーブル構造に関する情報と、暗号化および署名の方法が含まれます。この例では、項目エンクリプタとやり取りするため、DynamoDB 暗号化コンテキストを明示的に作成します。[クライアントのヘルパークラス](python-using.md#python-helpers)では、DynamoDB 暗号化コンテキストが作成されます。  
パーティションキーおよびソートキーを取得するには、[TableInfo](python-using.md#python-helpers) ヘルパークラスのプロパティを使用できます。  

```
index_key = {
    'partition_attribute': 'value1',
    'sort_attribute': 55
}

encryption_context = EncryptionContext(
    table_name=table_name,
    partition_key_name=table_info.primary_index.partition,
    sort_key_name=table_info.primary_index.sort,
    attributes=dict_to_ddb(index_key)
)
```

ステップ 5: 属性アクションオブジェクトを作成する  
[属性アクション](DDBEC-legacy-concepts.md#legacy-attribute-actions)は、項目の各属性に対して実行するアクションを項目エンクリプタに指示します。この例の `AttributeActions` オブジェクトは、署名されているが暗号されていないプライマリキー属性と、無視される `test` 属性を除き、すべての項目を暗号化し、署名します。  
項目エンクリプタを使用して直接やり取りし、デフォルトアクションが `ENCRYPT_AND_SIGN` の場合、プライマリキーの代替アクションを指定する必要があります。`set_index_keys` メソッドを使用できます。このメソッドでは、プライマリキーに `SIGN_ONLY`、デフォルトアクションの場合には `DO_NOTHING` が使用されます。  
プライマリキーを指定するために、この例では、[TableInfo](python-using.md#python-helpers) オブジェクトのインデックスキーを使用します。これは、DynamoDB への呼び出しによって指定されます。この技術は、ハードコーディングのプライマリキー名より安全です。  

```
actions = AttributeActions(
    default_action=CryptoAction.ENCRYPT_AND_SIGN,
    attribute_actions={'test': CryptoAction.DO_NOTHING}
)
actions.set_index_keys(*table_info.protected_index_keys())
```

ステップ 6: 項目の設定を作成する  
DynamoDB 暗号化クライアントを設定するには、テーブル項目の [CryptoConfig](https://aws-dynamodb-encryption-python.readthedocs.io/en/latest/lib/encrypted/config.html) 設定で先ほど作成したオブジェクトを使用します。クライアントのヘルパークラスでは、CryptoConfig が作成されます。  

```
crypto_config = CryptoConfig(
    materials_provider=kms_cmp,
    encryption_context=encryption_context,
    attribute_actions=actions
)
```

ステップ 7: 項目を暗号化する  
このステップでは、項目を暗号化および署名しますが、DynamoDB テーブルには入力されません。  
クライアントのヘルパークラスを使用するときに、項目は透過的に暗号化されて署名され、その後、ヘルパークラスの `put_item` メソッドを呼び出すときに、DynamoDB テーブルに追加されます。項目エンクリプタを直接使用する場合、暗号化および入力アクションは独立しています。  
まず、プレーンテキスト項目を作成します。  

```
plaintext_item = {
    'partition_attribute': 'value1',
    'sort_key': 55,
    'example': 'data',
    'numbers': 99,
    'binary': Binary(b'\x00\x01\x02'),
    'test': 'test-value'
}
```
次に、その項目を暗号化して署名します。`encrypt_python_item` メソッドでは、`CryptoConfig` 設定オブジェクトが必要です。  

```
encrypted_item = encrypt_python_item(plaintext_item, crypto_config)
```

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

```
table.put_item(Item=encrypted_item)
```

暗号化された項目を表示するには、元の `get_item` オブジェクトの `table` メソッドを呼び出します。`encrypted_table` オブジェクトではありません。これにより、検証および復号せずに、DynamoDB テーブルより項目を取得することができます。

```
encrypted_item = table.get_item(Key=partition_key)['Item']
```

次の画像は、暗号化された署名済みのテーブル項目の例の一部を示します。

暗号化された属性値は、バイナリデータです。プライマリキー属性の名前および値 (`partition_attribute` および `sort_attribute`) と、`test` 属性は、プレーンテキスト形式のままです。また、この出力は、署名を含む属性 (`*amzn-ddb-map-sig*`) と[マテリアル説明属性](DDBEC-legacy-concepts.md#legacy-material-description) (`*amzn-ddb-map-desc*`) を示します。

![\[暗号化されて署名された項目の抜粋\]](http://docs.aws.amazon.com/ja_jp/database-encryption-sdk/latest/devguide/images/encrypted-item-closeup.png)


# データモデルの変更
<a name="data-model"></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)」を参照してください。

項目を暗号化または復号するたびに、暗号化して署名する属性、署名する (ただし、暗号化はしない) 属性、および無視する属性を DynamoDB 暗号化クライアントに伝達する[属性アクション](DDBEC-legacy-concepts.md#legacy-attribute-actions)を指定する必要があります。属性アクションは、暗号化された項目に保存されないため、DynamoDB 暗号化クライアントは属性アクションを自動的に処理しません。

**重要**  
DynamoDB Encryption Client は、既存の暗号化されていない DynamoDB テーブルデータの暗号化をサポートしていません。

データモデルを変更するたびに、つまり、テーブル項目から属性を追加または削除すると、エラーが発生する危険性があります。指定した属性アクションが、項目のすべての属性で構成されていない場合、その項目は、意図した方法で暗号化および署名されない場合があります。さらに重要な点として、項目の復号時に指定する属性アクションが、項目の暗号化時に指定した属性アクションと異なる場合は、署名検証が失敗する場合があります。

たとえば、項目の暗号化に使用する属性アクションで、`test` 属性に署名するよう指示した場合、その項目の署名には `test` 属性が含まれます。項目の復号に使用する属性アクションが、`test` 属性で構成されていない場合、クライアントは `test` 属性を含まない署名の検証を試みるため、検証は失敗します。

これは、DynamoDB 暗号化クライアントがすべてのアプリケーションの項目に対して同じ署名を計算する必要があるため、複数のアプリケーションが同じ DynamoDB 項目の読み取りおよび書き込みを行う場合に特に問題になります。また、属性アクションの変更がすべてのホストに反映される必要があるため、分散アプリケーションでも問題になります。DynamoDB テーブルが 1 つのプロセスで 1 つのホストによってアクセスされる場合でも、ベストプラクティスプロセスを確立すると、プロジェクトが複雑になった場合にエラーを防ぐことができます。

テーブル項目を読み取ることができない署名検証エラーを回避するには、次のガイダンスを使用します。
+ [属性の追加](#add-attribute) — 新しい属性によって属性アクションが変更される場合は、項目に新しい属性を含める前に属性アクションの変更を完全にデプロイします。
+ [属性の削除](#remove-attribute) - 項目で属性の使用を中止する場合は、属性アクションを変更しないでください。
+ アクションの変更 - 属性アクション設定を使用してテーブル項目を暗号化した後は、テーブル内のすべての項目を再暗号化しなければ、デフォルトのアクションまたは既存の属性のアクションを安全に変更することはできません。

署名検証エラーは解決が非常に困難な場合があるため、最善の方法は、それらのエラーを回避することです。

**Topics**
+ [属性の追加](#add-attribute)
+ [属性の削除](#remove-attribute)

## 属性の追加
<a name="add-attribute"></a>

テーブル項目に新しい属性を追加する場合、属性アクションの変更が必要になることがあります。署名検証エラーを回避するために、この変更を 2 ステージのプロセスで実装することをお勧めします。第 2 ステージを開始する前に、第 1 ステージが完了していることを確認します。

1. テーブルの読み取りまたは書き込みを行うすべてのアプリケーションで属性アクションを変更します。これらの変更をデプロイして、更新がすべての送信先ホストに反映されていることを確認します。

1. テーブル項目の新しい属性に値を書き込みます。

この 2 ステージのアプローチでは、すべてのアプリケーションおよびホストに同じ属性アクションが設定され、新しい属性が見つかる前に同じ署名が計算されます。これは、属性のアクションが*何もしない* (暗号化または署名しない) 場合でも重要です。その理由は、一部の暗号化では暗号化と署名がデフォルトであるためです。

次の例は、このプロセスの第 1 ステージのコードを示しています。新しい項目属性 `link` が追加されます。これには、別のテーブル項目へのリンクが保存されます。このリンクはプレーンテキストのままにする必要があるため、この例では署名のみアクションを割り当てます。この変更を完全にデプロイし、すべてのアプリケーションおよびホストに新しい属性アクションがあることを確認したら、テーブル項目で `link` 属性の使用を開始します。

------
#### [ Java DynamoDB Mapper ]

`DynamoDB Mapper` と `AttributeEncryptor` を使用すると、デフォルトでは、プライマリキーを除く属性がすべて暗号化されます。これらの属性は署名されますが、暗号化はされません。署名のみアクションを指定するには、`@DoNotEncrypt` 注釈を使用します。

この例では、新しい `link` 属性に `@DoNotEncrypt` 注釈を使用します。

```
@DynamoDBTable(tableName = "ExampleTable")
public static final class DataPoJo {
  private String partitionAttribute;
  private int sortAttribute;
  private String link;

  @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 = "link")
  @DoNotEncrypt
  public String getLink() {
    return link;
  }

  public void setLink(String link) {
    this.link = link;
  }

  @Override
  public String toString() {
    return "DataPoJo [partitionAttribute=" + partitionAttribute + ",
        sortAttribute=" + sortAttribute + ",
        link=" + link + "]";
  }
}
```

------
#### [ Java DynamoDB encryptor ]

 下位レベルの DynamoDB エンクリプタでは、属性ごとにアクションを設定する必要があります。この例では、switch 文を使用します。デフォルトは `encryptAndSign` で、パーティションキー、ソートキー、および新しい `link` 属性に例外が指定されています。この例では、リンク属性コードが使用前に完全にデプロイされていない場合、リンク属性の暗号化および署名を行うアプリケーションや、リンク属性の署名のみを行うアプリケーションがあります。

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

------
#### [ Python ]

Python 用の DynamoDB 暗号化クライアントでは、すべての属性にデフォルトのアクションを指定してから、例外を指定できます。

Python [クライアントのヘルパークラス](python-using.md#python-helpers)を使用している場合は、プライマリキー属性の属性アクションを指定する必要はありません。クライアントのヘルパークラスを使用して、プライマリキーを暗号化することはできません。ただし、クライアントのヘルパークラスを使用していない場合は、パーティションキーとソートキーに SIGN\$1ONLY アクションを設定する必要があります。パーティションキーまたはソートキーを誤って暗号化した場合、完全なテーブルスキャンを行わないとデータを復元できません。

この例では、`SIGN_ONLY` アクションを取得する新しい `link` 属性の例外を指定します。

```
actions = AttributeActions(
    default_action=CryptoAction.ENCRYPT_AND_SIGN,
    attribute_actions={
      'example': CryptoAction.DO_NOTHING,  
      'link': CryptoAction.SIGN_ONLY
    }
)
```

------

## 属性の削除
<a name="remove-attribute"></a>

DynamoDB 暗号化クライアントで暗号化された項目で属性が不要になった場合は、その属性の使用を停止できます。ただし、その属性のアクションを削除または変更しないでください。その削除または変更を行ってから、その属性を持つ項目が見つかった場合、その項目に対して計算された署名は元の署名と一致せず、署名の検証は失敗します。

コードから属性のすべてのトレースを削除したいと思うかもしれませんが、項目を削除するのではなく、項目が使用されなくなったというコメントを追加してください。完全なテーブルスキャンを実行して属性のすべてのインスタンスを削除しても、その属性を持つ暗号化された項目は、設定のどこかでキャッシュされるか、または処理中になる可能性があります。

# DynamoDB 暗号化クライアントアプリケーションの問題のトラブルシューティング
<a name="troubleshooting"></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)」を参照してください。

このセクションでは、DynamoDB 暗号化クライアントを使用する際に直面する可能性のある問題を示すとともに、その問題の解決方法を提案します。

DynamoDB 暗号化クライアントに関するフィードバックを提供するには、[aws-dynamodb-encryption-java](https://github.com/aws/aws-dynamodb-encryption-java/) または [aws-dynamodb-encryption-python](https://github.com/aws/aws-dynamodb-encryption-python/) GitHub リポジトリに問題を提出します。

このドキュメントに関するフィードバックを提供するには、任意のページのフィードバックリンクを使用します。

**Topics**
+ [アクセスが拒否されました](#kms-permissions)
+ [署名の検証失敗](#change-data-model)
+ [古いバージョンのグローバルテーブルの問題](#fix-global-tables)
+ [最新プロバイダーのパフォーマンスが悪い](#mrp-ttl-delay)

## アクセスが拒否されました
<a name="kms-permissions"></a>

**問題**: アプリケーションから必要なリソースにアクセスできない。

**提案**: 必要なアクセス許可について説明します。アプリケーションが実行されているセキュリティコンテキストにこのアクセス許可を追加します。

**詳細**

DynamoDB 暗号化クライアントライブラリを使用するアプリケーションを実行するには、そのコンポーネントを使用するためのアクセス許可が呼び出し元に必要です。それ以外の場合、必要な要素への発信者のアクセスは拒否されます。
+ DynamoDB 暗号化クライアントは、Amazon Web Services (AWS) アカウントを必要とせず、どの AWS サービスにも依存しません。ただし、アプリケーションが を使用する場合は AWS、アカウントを使用するアクセス許可を持つ [AWS アカウント](https://aws.amazon.com/premiumsupport/knowledge-center/create-and-activate-aws-account/)および ユーザーが必要です。 [https://docs.aws.amazon.com/IAM/latest/UserGuide/getting-started_create-admin-group.html](https://docs.aws.amazon.com/IAM/latest/UserGuide/getting-started_create-admin-group.html)
+ DynamoDB 暗号化クライアントには Amazon DynamoDB は必要ありません。ただし、クライアントを使用するアプリケーションで DynamoDB テーブルを作成する、テーブルに項目を入力する、またはテーブルから項目を取得する場合、呼び出し元には、 AWS アカウントで必要な DynamoDB オペレーションを使用するためのアクセス許可が必要です。詳細については、*Amazon DynamoDB デベロッパーガイド*の[アクセスコントロールのトピック](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/access-control-overview.html)を参照してください。
+ アプリケーションが、Python 用 DynamoDB 暗号化クライアントで[クライアントヘルパークラス](python-using.md#python-helpers)を使用する場合、呼び出し元には、DynamoDB [DescribeTable](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_DescribeTable.html) オペレーションを呼び出すためのアクセス許可が必要です。
+ DynamoDB 暗号化クライアントには AWS Key Management Service () は必要ありませんAWS KMS。ただし、アプリケーションが [Direct KMS マテリアルプロバイダー](direct-kms-provider.md)を使用している場合、または が使用するプロバイダーストアで[最新](most-recent-provider.md)プロバイダーを使用している場合 AWS KMS、呼び出し元には、 AWS KMS [GenerateDataKey](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKey.html) および [Decrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.html) オペレーションを使用するアクセス許可が必要です。

## 署名の検証失敗
<a name="change-data-model"></a>

**問題**: 署名検証に失敗したため、項目を復号できない。また、項目は、意図したように暗号化および署名されていない場合があります。

**提案**: 指定した属性アクションが、項目内のすべての属性で構成されていることを確認してください。項目を復号する場合は、項目の暗号化に使用するアクションと一致する属性アクションを指定します。

**詳細**

指定する[属性アクション](DDBEC-legacy-concepts.md#legacy-attribute-actions)によって、DynamoDB 暗号化クライアントに、暗号化して署名する属性、署名する (ただし、暗号化はしない) 属性、および無視する属性が伝達されます。

指定した属性アクションが、項目のすべての属性で構成されていない場合、その項目は、意図した方法で暗号化および署名されない場合があります。項目の復号時に指定する属性アクションが、項目の暗号化時に指定した属性アクションと異なる場合は、署名検証が失敗する場合があります。これは、分散アプリケーション固有の問題で、新しい属性アクションがすべてのホストに反映されていない可能性があります。

署名の検証エラーは解決が困難です。それらのエラーを防ぐために、データモデルの変更時に追加の対策を講じてください。詳細については、「[データモデルの変更](data-model.md)」を参照してください。

## 古いバージョンのグローバルテーブルの問題
<a name="fix-global-tables"></a>

**問題**: 署名の検証が失敗するため、古いバージョンの Amazon DynamoDB グローバルテーブルの項目を復号できません。

**推奨**: 予約されたレプリケーションフィールドが暗号化または署名されないように属性アクションを設定します。

**詳細**

[DynamoDB グローバルテーブル](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GlobalTables.html)を使用して DynamoDB Encryption Client を使用できます。[マルチリージョン KMS キー](https://docs.aws.amazon.com/kms/latest/developerguide/multi-region-keys-overview.html)を持つグローバルテーブルを使用し、グローバルテーブルがレプリケートされるすべての AWS リージョン に KMS キーをレプリケートすることをお勧めします。

グローバルテーブルの[バージョン 2019.11.21](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/globaltables.V2.html) 以降、特別な設定を行うことなく、DynamoDB Encryption Client でグローバルテーブルを使用できるようになりました。ただし、グローバルテーブルの[バージョン 2017.11.29](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/globaltables.V1.html) を使用する場合は、予約されたレプリケーションフィールドが暗号化または署名されていないことを確認する必要があります。

グローバルテーブルのバージョン 2017.11.29 を使用している場合は、次の属性の属性アクションを [Java](java-using.md#attribute-actions-java) で `DO_NOTHING` または [Python](python-using.md#python-attribute-actions) で `@DoNotTouch` に設定する必要があります。
+ `aws:rep:deleting`
+ `aws:rep:updatetime`
+ `aws:rep:updateregion`

他のバージョンのグローバルテーブルを使用している場合は、アクションは必要ありません。

## 最新プロバイダーのパフォーマンスが悪い
<a name="mrp-ttl-delay"></a>

**問題**: 特に DynamoDB 暗号化クライアントの新しいバージョンに更新すると、アプリケーションの応答性が低下します。

**提案**: 有効期限 (TTL) 値とキャッシュサイズを調整します。

**詳細**

最新のプロバイダーは、暗号化マテリアルの再利用を制限できるようにすることで、DynamoDB 暗号化クライアントを使用するアプリケーションのパフォーマンスを向上させるように設計されています。アプリケーションの最新プロバイダーを設定するときは、パフォーマンスの向上と、キャッシュと再利用によって生じるセキュリティ上の問題とのバランスを取る必要があります。

DynamoDB 暗号化クライアントの新しいバージョンでは、有効期限 (TTL) の値によって、キャッシュされた暗号化マテリアルプロバイダー (CMP) の使用期間が決定されます。TTL により、最新プロバイダーが新しいバージョンの CMP をチェックする頻度も決定されます。

TTL が長すぎると、アプリケーションがビジネスルールやセキュリティ基準に違反する可能性があります。TTL が短すぎると、プロバイダーストアへの頻繁な呼び出しによって、プロバイダーストアがアプリケーションや、サービスアカウントを共有する他のアプリケーションからのリクエストを抑制する可能性があります。この問題を解決するには、レイテンシーと可用性の目標を満たし、セキュリティ基準に準拠する値に TTL とキャッシュサイズを調整します。詳細については、[有効期限 (TTL) の値を設定する](most-recent-provider.md#most-recent-provider-ttl) を参照してください