

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

# レガシー 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) を参照してください