

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

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


****  

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

検索可能な暗号化を使用すると、データベース全体を復号することなく、暗号化されたレコードを検索できます。これはビーコンを使用して実現されます。ビーコンは、フィールドに書き込まれるプレーンテキストの値と、実際にデータベースに格納される暗号化された値との間のマップを作成します。 AWS Database Encryption SDK は、レコードに追加する新しいフィールドにビーコンを保存します。使用するビーコンのタイプに応じて、暗号化されたデータに対して、完全一致検索や、よりカスタマイズされた複雑なクエリを実行できます。

**注記**  
 AWS Database Encryption SDK の検索可能な暗号化は、検索可能な対称暗号化など、学術研究で定義された[検索可能な対称暗号化とは異なります](https://dl.acm.org/doi/10.1145/1180405.1180417)。



ビーコンは、フィールドのプレーンテキストの値と暗号化された値の間のマップを作成する、切り詰められた Hash-Based Message Authentication Code (HMAC) タグです。検索可能な暗号化用に設定された暗号化されたフィールドに新しい値を書き込むと、 AWS Database Encryption SDK はプレーンテキスト値で HMAC を計算します。この HMAC 出力は、そのフィールドのプレーンテキストの値と 1 対 1 (1:1) で一致します。HMAC 出力は切り詰められ、複数の個別のプレーンテキストの値が、切り詰められた同じ HMAC タグにマッピングされます。これらの誤検知により、不正ユーザーは、プレーンテキストの値に関する特徴的な情報を識別しにくくなります。ビーコンをクエリすると、 AWS Database Encryption SDK はこれらの誤検知を自動的に除外し、クエリのプレーンテキスト結果を返します。

各ビーコンについて生成される誤検知の平均数は、切り詰めた後に残っているビーコンの長さによって決まります。実装に適切なビーコンの長さを決定する方法については、「[ビーコンの長さの決定](choosing-beacon-length.md)」を参照してください。

**注記**  
検索可能な暗号化は、データが入力されていない新しいデータベースで実装されるように設計されています。既存のデータベースで設定されたビーコンは、データベースにアップロードされた新しいレコードのみをマッピングします。ビーコンは既存のデータをマッピングできなくなります。

**トピック**
+ [ビーコンが適しているデータセット](#are-beacons-right-for-me)
+ [検索可能な暗号化のシナリオ](#beacon-overview-example)

## ビーコンが適しているデータセット
<a name="are-beacons-right-for-me"></a>

ビーコンを使用して、暗号化されたデータをクエリすると、クライアント側の暗号化されたデータベースに関連するパフォーマンスコストが削減されます。ビーコンを使用する場合、クエリの効率性と、データの分布に関して明らかになる情報の量との間には、固有のトレードオフが存在します。ビーコンはフィールドの暗号化状態を変更しません。 AWS Database Encryption SDK を使用してフィールドを暗号化して署名すると、フィールドのプレーンテキスト値がデータベースに公開されることはありません。データベースには、フィールドのランダム化および暗号化された値が格納されます。

ビーコンは、計算元の暗号化されたフィールドと一緒に格納されます。これは、不正ユーザーが暗号化されたフィールドのプレーンテキストの値を表示できない場合でも、ビーコンに対して統計分析を実行してデータセットの分布の詳細を知ることができ、極端な場合には、ビーコンがマッピングするプレーンテキストの値を識別できる場合があることを意味します。ビーコンを設定する方法によって、これらのリスクを軽減できます。特に、[適切なビーコンの長さを選択](choosing-beacon-length.md)することは、データセットの機密性を維持するのに役立ちます。

**セキュリティとパフォーマンス**
+ ビーコンが短いほど、セキュリティはより強くなります。
+ ビーコンが長いほど、パフォーマンスはより高くなります。

検索可能な暗号化では、すべてのデータセットについて、必要なレベルのパフォーマンスとセキュリティの両方を提供できない場合があります。ビーコンを設定する前に、脅威モデル、セキュリティ要件、パフォーマンスのニーズを確認してください。

検索可能な暗号化がデータセットに適しているかどうかを判断する際には、データセットの一意性に関する次の要件を考慮してください。

**ディストリビューション**  
ビーコンによって維持されるセキュリティの強度は、データセットの分布によって異なります。検索可能な暗号化用に暗号化されたフィールドを設定すると、 AWS Database Encryption SDK はそのフィールドに書き込まれたプレーンテキスト値で HMAC を計算します。特定のフィールドについて計算されるすべてのビーコンは、テナンシーごとに個別のキーを使用するマルチテナンシーデータベースを除き、同じキーを使用して計算されます。これは、同じプレーンテキストの値がフィールドに複数回書き込まれる場合、そのプレーンテキストの値のすべてについて同じ HMAC タグが作成されることを意味します。  
非常に一般的な値を含むフィールドからビーコンを構築しないようにしてください。例えば、イリノイ州のすべての居住者の住所を格納するデータベースを考えてみましょう。暗号化された `City` フィールドからビーコンを構築する場合、シカゴに居住しているイリノイ州の母集団の割合が大きいため、「シカゴ」について計算されたビーコンは過剰に出現します。不正ユーザーが暗号化された値とビーコンの値を読み取ることしかできない場合でも、ビーコンがこの分布を保持していれば、どのレコードにシカゴの居住者のデータが含まれているかを特定できる可能性があります。分布に関して明らかになる特徴的な情報の量を最小限にするには、ビーコンを十分に切り詰める必要があります。この不均一な分布をわからなくするために必要な長さにビーコンを設定すると、パフォーマンスに大きな悪影響が及び、アプリケーションのニーズを満たせない可能性があります。  
データセットの分布を注意深く分析して、ビーコンをどの程度切り詰める必要があるかを判断する必要があります。切り詰めた後に残るビーコンの長さは、分布に関して特定できる統計情報の量に直接相関します。データセットに関して明らかになる特徴的な情報の量を十分かつ最小限に抑えるために、ビーコンをより短くすることを選択する必要がある場合があります。  
極端な場合には、不均一に分布したデータセットについて、パフォーマンスとセキュリティのバランスを効果的に実現できるビーコンの長さを計算することができません。例えば、希少疾患の医学的検査の結果を格納するフィールドからビーコンを構築しないでください。`NEGATIVE` の結果はデータセット内で大幅に増えることが想定されるため、`POSITIVE` の結果は、それがどれだけ稀であるかによって簡単に識別できます。フィールドで可能な値が 2 つしかない場合、分布をわからなくするのは非常に困難です。分布をわからなくするのに十分な程度にまでビーコンを短くすると、すべてのプレーンテキストの値が同じ HMAC タグにマッピングされます。ビーコンをより長くすると、どのビーコンがプレーンテキストの `POSITIVE` の値にマッピングされているのかが明らかになります。

**相関関係**  
相関する値を持つフィールドから個別のビーコンを構築しないことを強くお勧めします。相関するフィールドから構築されたビーコンでは、各データセットの分布に関して、不正ユーザーに対して明らかになる情報の量を十分かつ最小限に抑えるために、ビーコンをより短くする必要があります。ビーコンをどの程度切り詰める必要があるかを判断するには、エントロピーや相関する値の結合分布などのデータセットを注意深く分析する必要があります。結果として得られるビーコンの長さがパフォーマンスのニーズを満たさない場合、ビーコンはデータセットに適していない可能性があります。  
例えば、郵便番号は 1 つの都市にのみ関連付けられている可能性が高いため、`City` フィールドと `ZIPCode` フィールドから 2 つの別個のビーコンを構築すべきではありません。通常、ビーコンによって生成される誤検知により、不正ユーザーは、データセットに関する特徴的な情報を識別しにくくなります。ただし、`City` および `ZIPCode` フィールド間の相関関係を知ることで、不正ユーザーは、どの結果が誤検知であるかを簡単に特定し、異なる郵便番号を区別できます。  
また、同じプレーンテキストの値を含むフィールドからビーコンを構築することも避けてください。例えば、`mobilePhone` および `preferredPhone` フィールドは同じ値を保持する可能性が高いため、これらのフィールドからビーコンを構築すべきではありません。両方のフィールドから異なるビーコンを構築すると、 AWS Database Encryption SDK は異なるキーで各フィールドのビーコンを作成します。これにより、同じプレーンテキストの値について 2 つの異なる HMAC タグが作成されます。2 つの異なるビーコンに同じ誤検知が発生する可能性は低く、不正ユーザーは異なる電話番号を区別できる可能性があります。

相関するフィールドがデータセットに含まれている場合や、分布が不均一である場合でも、ビーコンをより短くすることで、データセットの機密性を維持するビーコンを構築できる場合があります。ただし、ビーコンの長さは、データセット内のすべての一意の値が多数の誤検知を生成し、データセットに関して明らかになる特徴的な情報の量を効果的かつ最小限に抑えることを保証するものではありません。ビーコンの長さによって推定されるのは、生成される誤検知の平均数のみです。データセットが不均一に分布しているほど、生成される誤検知の平均数を決定する際のビーコンの長さの有効性は低くなります。

ビーコンを構築するフィールドの分布を慎重に検討し、セキュリティ要件を満たすためにビーコンの長さをどの程度切り詰める必要があるのかを検討してください。この章の次のトピックは、ビーコンが統一的に分布しており、相関データが含まれていないことを前提としています。

## 検索可能な暗号化のシナリオ
<a name="beacon-overview-example"></a>

次の例は、検索可能な暗号化のシンプルなソリューションを示しています。アプリケーションでは、この例で使用されているフィールド例は、ビーコンの分布および相関の一意性に関する推奨事項を満たしていない可能性があります。この章の検索可能な暗号化の概念を読む際に、この例を参考として使用できます。

会社の従業員データを追跡する `Employees` という名前のデータベースについて考えてみましょう。データベース内の各レコードには、EmployeeID、LastName、FirstName、および Address と呼ばれるフィールドが含まれています。`Employees` データベース内の各フィールドは、プライマリキー `EmployeeID` によって識別されます。

データベース内のプレーンテキストレコードの例を次に示します。

```
{
    "EmployeeID": 101,
    "LastName": "Jones",
    "FirstName": "Mary",
    "Address": {
                "Street": "123 Main",
                "City": "Anytown",
                "State": "OH",
                "ZIPCode": 12345
    }
}
```

[暗号化アクション](concepts.md#crypt-actions)で `LastName` フィールドと `FirstName` フィールドを `ENCRYPT_AND_SIGN` とマークした場合、これらのフィールドの値は、データベースにアップロードされる前にローカルで暗号化されます。アップロードされる暗号化データは完全にランダム化されており、データベースはこのデータが保護されているとは認識しません。典型的なデータエントリを検出するだけです。つまり、実際にデータベースに格納されるレコードは次のようになります。

```
{
    "PersonID": 101,
    "LastName": "1d76e94a2063578637d51371b363c9682bad926cbd",
    "FirstName": "21d6d54b0aaabc411e9f9b34b6d53aa4ef3b0a35",
    "Address": {
                "Street": "123 Main",
                "City": "Anytown",
                "State": "OH",
                "ZIPCode": 12345
    }
}
```

`LastName` フィールド内の完全一致を検索するために、データベースをクエリする必要がある場合は、`LastName` フィールドに書き込まれるプレーンテキストの値を、データベースに格納される暗号化された値にマッピングするように、LastName という名前の[標準ビーコンを設定](configure-beacons.md#config-standard-beacons)します。

このビーコンは、`LastName` フィールド内のプレーンテキストの値から HMAC を計算します。各 HMAC 出力は切り詰められるため、プレーンテキストの値と完全に一致しなくなります。例えば、`Jones` の完全なハッシュと切り詰められたハッシュは次のようになります。

**完全なハッシュ**

`2aa4e9b404c68182562b6ec761fcca5306de527826a69468885e59dc36d0c3f824bdd44cab45526f70a2a18322000264f5451acf75f9f817e2b35099d408c833`

**切り詰められたハッシュ**

`b35099d408c833`

標準ビーコンを設定した後、`LastName` フィールド上で一致検索を実行できます。例えば、`Jones` を検索する場合は、LastName ビーコンを使用して次のクエリを実行します。

```
LastName = Jones
```

 AWS Database Encryption SDK は誤検出を自動的に除外し、クエリのプレーンテキストの結果を返します。

# ビーコン
<a name="beacons"></a>


****  

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

ビーコンは、フィールドに書き込まれるプレーンテキストの値と、実際にデータベースに格納される暗号化された値の間のマップを作成する、切り詰められた Hash-Based Message Authentication Code (HMAC) タグです。ビーコンはフィールドの暗号化状態を変更しません。ビーコンは、フィールドのプレーンテキストの値について HMAC を計算し、それを暗号化された値と一緒に格納します。この HMAC 出力は、そのフィールドのプレーンテキストの値と 1 対 1 (1:1) で一致します。HMAC 出力は切り詰められ、複数の個別のプレーンテキストの値が、切り詰められた同じ HMAC タグにマッピングされます。これらの誤検知により、不正ユーザーは、プレーンテキストの値に関する特徴的な情報を識別しにくくなります。

ビーコンは、[暗号化アクション](concepts.md#crypt-actions)`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`で `ENCRYPT_AND_SIGN`、`SIGN_ONLY`、または とマークされたフィールドからのみ構築できます。ビーコン自体は署名も暗号化もされません。`DO_NOTHING` とマークされているフィールドを使用してビーコンを構築することはできません。

設定するビーコンのタイプによって、実行できるクエリのタイプが決まります。検索可能な暗号化をサポートするビーコンには 2 つのタイプがあります。標準ビーコンは、一致検索を実行します。複合ビーコンは、リテラルプレーンテキスト文字列と標準ビーコンを組み合わせて、複雑なデータベースオペレーションを実行します。[ビーコンを設定](configure-beacons.md)した後、暗号化されたフィールドを検索する前に、各ビーコンについてセカンダリインデックスを設定する必要があります。詳細については、「[ビーコンを使用したセカンダリインデックスの設定](ddb-searchable-encryption.md#ddb-beacon-indexes)」を参照してください。

**Topics**
+ [標準ビーコン](#standard-beacon-overview)
+ [複合ビーコン](#compound-beacon-overview)

## 標準ビーコン
<a name="standard-beacon-overview"></a>

標準ビーコンは、データベースで検索可能な暗号化を実装する最も簡単な方法です。単一の暗号化されたフィールドまたは仮想フィールドについてのみ一致検索を実行できます。標準ビーコンの設定方法については、「[標準ビーコンの設定](configure-beacons.md#config-standard-beacons)」を参照してください。



標準ビーコンが構築されるフィールドは、ビーコンソースと呼ばれます。これは、ビーコンがマッピングする必要があるデータの場所を識別します。ビーコンソースは、暗号化されたフィールドまたは仮想フィールドのいずれかです。各標準ビーコンのビーコンソースは一意である必要があります。同じビーコンソースで 2 つのビーコンを設定することはできません。

標準ビーコンを使用して、暗号化されたフィールドまたは仮想フィールドの等価検索を実行できます。または、複合ビーコンを構築して、より複雑なデータベースオペレーションを実行することもできます。標準ビーコンの整理と管理に役立つように、 AWS Database Encryption SDK には、標準ビーコンの用途を定義する以下のオプション*ビーコンスタイル*が用意されています。詳細については、[「ビーコンスタイルの定義](configure-beacons.md#define-beacon-styles)」を参照してください。

単一の暗号化されたフィールドに対して等価検索を実行する標準ビーコンを作成することも、仮想フィールドを作成して複数の `ENCRYPT_AND_SIGN`、、`SIGN_ONLY`および `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`フィールドの連結に対して等価検索を実行する標準ビーコンを作成することもできます。



**仮想フィールド**  
仮想フィールドは、1 つ以上のソースフィールドから構築された概念的なフィールドです。仮想フィールドを作成しても、レコードに新しいフィールドは書き込まれません。仮想フィールドは、データベースに明示的に格納されません。これは、フィールドの特定のセグメントを識別する方法、またはレコード内の複数のフィールドを連結して特定のクエリを実行する方法についてビーコンに指示を与えるために、標準ビーコン設定で使用されます。仮想フィールドには少なくとも 1 つの暗号化されたフィールドが必要です。  
次の例は、仮想フィールドを使用して実行できる変換とクエリのタイプを示しています。アプリケーションでは、この例で使用されているフィールド例は、ビーコンの[分布](searchable-encryption.md#searchable-encryption-distribution)および[相関](searchable-encryption.md#searchable-encryption-correlated-values)の一意性に関する推奨事項を満たしていない可能性があります。
例えば、`FirstName` および `LastName` フィールドの連結に対して一致検索を実行する場合は、次のいずれかの仮想フィールドを作成することが考えられます。  
+ `FirstName` フィールドの最初の文字と、それに続く `LastName` フィールドから構築される仮想 `NameTag` フィールド (すべて小文字)。この仮想フィールドを使用すると、`NameTag=mjones` をクエリできます。
+ `LastName` フィールドと、それに続く `FirstName` フィールドから構築される仮想 `LastFirst` フィールド。この仮想フィールドを使用すると、`LastFirst=JonesMary` をクエリできます。
または、暗号化されたフィールドの特定のセグメントに対して一致検索を実行する場合は、クエリを実行するセグメントを識別する仮想フィールドを作成します。  
例えば、IP アドレスの最初の 3 つのセグメントを使用して暗号化された `IPAddress` フィールドをクエリする場合は、次の仮想フィールドを作成します。  
+ `Segments(‘.’, 0, 3)` から構築された仮想 `IPSegment` フィールド。この仮想フィールドを使用すると、`IPSegment=192.0.2` をクエリできます。クエリは、「192.0.2」で始まる `IPAddress` の値を持つすべてのレコードを返します。
仮想フィールドは一意である必要があります。2 つの仮想フィールドをまったく同じソースフィールドから構築することはできません。  
仮想フィールドとそれらを使用するビーコンの設定については、「[仮想フィールドの作成](configure-beacons.md#create-virtual-field)」を参照してください。

## 複合ビーコン
<a name="compound-beacon-overview"></a>

複合ビーコンは、クエリのパフォーマンスを改善するインデックスを作成し、より複雑なデータベースオペレーションを実行できるようにします。複合ビーコンを使用して、リテラルプレーンテキスト文字列と標準ビーコンを組み合わせて、単一のインデックスから 2 つの異なるレコードタイプをクエリしたり、ソートキーを使用してフィールドの組み合わせをクエリしたりするなど、暗号化されたレコードに対して複雑なクエリを実行できます。複合ビーコンソリューションの例については、「[ビーコンタイプを選択する](choosing-beacon-type.md)」を参照してください。

複合ビーコンは、標準ビーコン、または標準ビーコンと署名付きフィールドの組み合わせから構築できます。これらは部分のリストから構築されます。すべての複合ビーコンには、ビーコンに含まれる `ENCRYPT_AND_SIGN` フィールドを識別する[暗号化された部分](configure-beacons.md#encrypted-parts)のリストが含まれている必要があります。すべての `ENCRYPT_AND_SIGN` フィールドは、標準ビーコンによって識別される必要があります。より複雑な複合ビーコンには、ビーコンに含まれるプレーンテキスト`SIGN_ONLY`または`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`フィールドを識別する[署名付きパート](configure-beacons.md#signed-parts)のリスト、および複合ビーコンがフィールドをアセンブルできるすべての可能な方法を識別するコン[ストラクタパート](configure-beacons.md#constructor-parts)のリストが含まれる場合があります。

**注記**  
 AWS Database Encryption SDK は、プレーンテキスト`SIGN_ONLY`と`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`フィールドから完全に設定できる*署名付きビーコン*もサポートしています。署名付きビーコンは、署名されたが暗号化されていないフィールドに対してインデックスを作成し、複雑なクエリを実行する複合ビーコンの一種です。詳細については、「[署名付きビーコンの作成](configure.md#signed-beacons)」を参照してください。

複合ビーコンの設定については、「[複合ビーコンの設定](configure-beacons.md#config-compound-beacons)」を参照してください。

複合ビーコンを設定する方法によって、実行できるクエリのタイプが決まります。例えば、一部の暗号化および署名付きの部分をオプションにして、クエリの柔軟性を高めることができます。複合ビーコンが実行できるクエリのタイプの詳細については、「[ビーコンのクエリ](using-beacons.md#querying-beacons)」を参照してください。

# ビーコンの計画
<a name="plan-searchable-encryption"></a>


****  

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

ビーコンは、データが入力されていない新しいデータベースに実装されるように設計されています。既存のデータベースで設定されたビーコンは、データベースに書き込まれる新しいレコードのみをマッピングします。ビーコンはフィールドのプレーンテキストの値から計算されます。フィールドが暗号化されると、ビーコンは既存のデータをマッピングできなくなります。ビーコンを持つ新しいレコードを書き込んだ後に、そのビーコンの設定を更新することはできません。ただし、レコードに追加する新しいフィールドに新しいビーコンを追加できます。

検索可能な暗号化を実装するには、[AWS KMS 階層キーリング](use-hierarchical-keyring.md)を使用して、レコードを保護するために使用されるデータキーを生成、暗号化、および復号する必要があります。詳細については、「[検索可能な暗号化のための階層キーリングの使用](use-hierarchical-keyring.md#searchable-encryption-hierarchical-keyrings)」を参照してください。

検索可能な暗号化のために[ビーコン](searchable-encryption.md#beacon-definition)を設定する前に、暗号化要件、データベースのアクセスパターン、および脅威モデルを確認して、データベースに最適なソリューションを決定する必要があります。

設定する[ビーコンのタイプ](beacons.md)によって、実行できるクエリのタイプが決まります。標準ビーコン設定で指定する[ビーコンの長さ](choosing-beacon-length.md)によって、特定のビーコンについて生成される誤検知の想定数が決まります。ビーコンを設定する前に、実行する必要があるクエリのタイプを特定して計画することを強くお勧めします。ビーコンを使用した後に設定を更新することはできません。

ビーコンを設定する前に、次のタスクを確認および完了することを強くお勧めします。
+ [ビーコンがデータセットに適しているかどうかを判断する](searchable-encryption.md#are-beacons-right-for-me)
+ [ビーコンのタイプを選択する](choosing-beacon-type.md)
+ [ビーコンの長さを選択する](choosing-beacon-length.md)
+ [ビーコン名を選択する](choosing-beacon-name.md)

データベースのために検索可能な暗号化ソリューションを計画する際には、ビーコンの一意性に関する次の要件に留意してください。
+ **すべての標準ビーコンには固有の[ビーコンソース](beacons.md#beacon-source)が必要です**

  同じ暗号化されたフィールドまたは仮想フィールドから複数の標準ビーコンを構築することはできません。

  ただし、単一の標準ビーコンを使用して複数の複合ビーコンを構築することはできます。
+ **既存の標準ビーコンと重複するソースフィールドを含む仮想フィールドを作成しないようにしてください**

  別の標準ビーコンを作成するために使用されたソースフィールドを含む仮想フィールドから標準ビーコンを構築すると、両方のビーコンのセキュリティが低下する可能性があります。

  詳細については、「[仮想フィールドのセキュリティに関する考慮事項](configure-beacons.md#virtual-field-considerations)」を参照してください。

## マルチテナンシーデータベースに関する考慮事項
<a name="planning-multitenant-beacons"></a>

マルチテナンシーデータベースで設定されたビーコンをクエリするには、レコードを暗号化したテナンシーに関連付けられた `branch-key-id` を格納するフィールドをクエリに含める必要があります。このフィールドは、[ビーコンキーソースを定義](use-hierarchical-keyring.md#beacon-key-source)する際に定義します。クエリが成功するには、このフィールドの値が、ビーコンの再計算に必要となる適切なビーコンキーマテリアルを識別する必要があります。

ビーコンを設定する前に、クエリに `branch-key-id` をどのように含めるかを決定する必要があります。クエリに `branch-key-id` を含めるさまざまな方法の詳細については、「[マルチテナンシーデータベース内のビーコンのクエリ](searchable-encryption-multitenant.md#query-multitenant-beacons)」を参照してください。

# ビーコンのタイプの選択
<a name="choosing-beacon-type"></a>


****  

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

検索可能な暗号化では、暗号化されたフィールドのプレーンテキストの値をビーコンでマッピングすることで、暗号化されたレコードを検索できます。設定するビーコンのタイプによって、実行できるクエリのタイプが決まります。

ビーコンを設定する前に、実行する必要があるクエリのタイプを特定して計画することを強くお勧めします。[ビーコンを設定](configure-beacons.md)した後、暗号化されたフィールドを検索する前に、各ビーコンについてセカンダリインデックスを設定する必要があります。詳細については、「[ビーコンを使用したセカンダリインデックスの設定](ddb-searchable-encryption.md#ddb-beacon-indexes)」を参照してください。

ビーコンは、フィールドに書き込まれるプレーンテキストの値と、データベースに実際に格納される暗号化された値との間のマップを作成します。2 つの標準ビーコンの値は、基になる同じプレーンテキストが含まれている場合でも比較できません。2 つの標準ビーコンは、同じプレーンテキストの値について 2 つの異なる HMAC タグを生成します。その結果、標準ビーコンは次のクエリを実行できません。
+ `beacon1 = beacon2`
+ `beacon1 IN (beacon2)`
+ `value IN (beacon1, beacon2, ...)`
+ `CONTAINS(beacon1, beacon2)`

上記のクエリは、複合ビーコンの[署名付きの部分](configure-beacons.md#signed-parts)を比較する場合にのみ実行できます。ただし、`CONTAINS` 演算子は例外です。この演算子は、アセンブルされたビーコンに含まれる暗号化または署名されたフィールドの値全体を識別するために複合ビーコンで使用できます。署名付きの部分を比較する場合、オプションで[暗号化された部分](configure-beacons.md#encrypted-parts)のプレフィックスを含めることができますが、フィールドの暗号化された値を含めることはできません。標準ビーコンおよび複合ビーコンが実行できるクエリのタイプの詳細については、「[ビーコンのクエリ](using-beacons.md#querying-beacons)」を参照してください。

データベースのアクセスパターンを確認する際には、次の検索可能な暗号化ソリューションを検討してください。次の例では、暗号化およびクエリに関するさまざまな要件を満たすためにどのビーコンを設定すべきかを定義します。

## 標準ビーコン
<a name="plan-standard-beacon"></a>

[標準ビーコン](beacons.md#standard-beacon-overview)は、一致検索のみを実行できます。標準ビーコンを使用して、次のクエリを実行できます。

### 暗号化された単一フィールドをクエリする
<a name="se-example1"></a>

暗号化されたフィールドについて特定の値を含むレコードを識別する場合は、標準ビーコンを作成します。

#### 例
<a name="example1"></a>

次の例では、生産施設の検査データを追跡する `UnitInspection` という名前のデータベースについて考えてみます。データベース内の各レコードには、`work_id`、`inspection_date`、`inspector_id_last4`、および `unit` と呼ばれるフィールドが含まれています。完全なインスペクター ID は 0～99,999,999 の数値です。ただし、データセットが統一的に分布するようにするために、`inspector_id_last4` はインスペクターの ID の下 4 桁のみを格納します。データベース内の各フィールドは、プライマリキー `work_id` によって識別されます。`inspector_id_last4` および `unit` フィールドは、[暗号化アクション](concepts.md#crypt-actions)で `ENCRYPT_AND_SIGN` とマークされます。

`UnitInspection` データベース内のプレーンテキストエントリの例を次に示します。

```
{
    "work_id": "1c7fcff3-6e74-41a8-b7f7-925dc039830b",
    "inspection_date": 2023-06-07,
    "inspector_id_last4": 8744,
    "unit": 229304973450   
}
```

**レコード内の暗号化された単一フィールドをクエリする**  
`inspector_id_last4` フィールドを暗号化する必要があるが、完全一致検索のためにクエリする必要もある場合は、`inspector_id_last4` フィールドから標準ビーコンを構築します。その後、標準ビーコンを使用してセカンダリインデックスを作成します。このセカンダリインデックスを使用して、暗号化された `inspector_id_last4` フィールドをクエリできます。

標準ビーコンの設定については、「[標準ビーコンの設定](configure-beacons.md#config-standard-beacons)」を参照してください。

### 仮想フィールドをクエリする
<a name="se-example2"></a>

[仮想フィールド](beacons.md#virtual-field)は、1 つ以上のソースフィールドから構築された概念的なフィールドです。暗号化されたフィールドの特定のセグメントについて一致検索を実行する場合、または複数のフィールドの連結に対して一致検索を実行する場合は、仮想フィールドから標準ビーコンを構築します。すべての仮想フィールドには、少なくとも 1 つの暗号化されたソースフィールドが含まれている必要があります。

#### 例
<a name="example2"></a>

次の例では、`Employees` データベースの仮想フィールドを作成します。`Employees` データベース内のプレーンテキストレコードの例を次に示します。

```
{
    "EmployeeID": 101,
    "SSN": 000-00-0000,
    "LastName": "Jones",
    "FirstName": "Mary",
    "Address": {
                "Street": "123 Main",
                "City": "Anytown",
                "State": "OH",
                "ZIPCode": 12345
    }
}
```

**暗号化されたフィールドのセグメントをクエリする**  
この例では、`SSN` フィールドは暗号化されています。  
社会保障番号の下 4 桁を使用して `SSN` フィールドをクエリする場合は、クエリを実行するセグメントを識別する仮想フィールドを作成します。  
`Suffix(4)` から構築された仮想 `Last4SSN` フィールドを使用すると、`Last4SSN=0000` をクエリできます。この仮想フィールドを使用して、標準ビーコンを構築します。その後、標準ビーコンを使用してセカンダリインデックスを作成します。このセカンダリインデックスを使用して、仮想フィールドをクエリできます。このクエリは、指定した下 4 桁で終わる `SSN` の値を持つすべてのレコードを返します。

**複数のフィールドの連結をクエリする**  
次の例は、仮想フィールドを使用して実行できる変換とクエリのタイプを示しています。アプリケーションでは、この例で使用されているフィールド例は、ビーコンの[分布](searchable-encryption.md#searchable-encryption-distribution)および[相関](searchable-encryption.md#searchable-encryption-correlated-values)の一意性に関する推奨事項を満たしていない可能性があります。
`FirstName` と `LastName` フィールドの連結に対して一致検索を実行する場合は、`FirstName` フィールドの最初の文字と、その後に続く `LastName` フィールドで構築される仮想 `NameTag` フィールドを作成できます (すべて小文字)。この仮想フィールドを使用して、標準ビーコンを構築します。その後、標準ビーコンを使用してセカンダリインデックスを作成します。このセカンダリインデックスを使用して、仮想フィールドの `NameTag=mjones` をクエリできます。  
少なくとも 1 つのソースフィールドを暗号化する必要があります。`FirstName` または `LastName` のいずれかを暗号化することも、両方を暗号化することもできます。プレーンテキストのソースフィールドは、[暗号化アクション](concepts.md#crypt-actions)`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`で `SIGN_ONLY`または としてマークする必要があります。

仮想フィールドとそれらを使用するビーコンの設定については、「[仮想フィールドの作成](configure-beacons.md#create-virtual-field)」を参照してください。

## 複合ビーコン
<a name="plan-compound-beacons"></a>

[複合ビーコン](beacons.md#compound-beacon-overview)は、リテラルプレーンテキスト文字列と標準ビーコンからインデックスを作成し、複雑なデータベースオペレーションを実行します。複号ビーコンを使用して、次のクエリを実行できます。

### 単一のインデックスで暗号化されたフィールドの組み合わせをクエリする
<a name="se-example3"></a>

単一のインデックスで暗号化されたフィールドの組み合わせをクエリする必要がある場合は、暗号化されたフィールドごとに構築された個々の標準ビーコンを組み合わせて単一のインデックスを形成する複合ビーコンを作成します。

複合ビーコンを設定した後、複合ビーコンをパーティションキーとして指定するセカンダリインデックスを作成して完全一致クエリを実行したり、ソートキーを使用してより複雑なクエリを実行したりできます。複合ビーコンをソートキーとして指定するセカンダリインデックスは、完全一致クエリや、よりカスタマイズされた複雑なクエリを実行できます。

#### 例
<a name="example3"></a>

次の例では、生産施設の検査データを追跡する `UnitInspection` という名前のデータベースについて考えてみます。データベース内の各レコードには、`work_id`、`inspection_date`、`inspector_id_last4`、および `unit` と呼ばれるフィールドが含まれています。完全なインスペクター ID は 0～99,999,999 の数値です。ただし、データセットが統一的に分布するようにするために、`inspector_id_last4` はインスペクターの ID の下 4 桁のみを格納します。データベース内の各フィールドは、プライマリキー `work_id` によって識別されます。`inspector_id_last4` および `unit` フィールドは、[暗号化アクション](concepts.md#crypt-actions)で `ENCRYPT_AND_SIGN` とマークされます。

`UnitInspection` データベース内のプレーンテキストエントリの例を次に示します。

```
{
    "work_id": "1c7fcff3-6e74-41a8-b7f7-925dc039830b",
    "inspection_date": 2023-06-07,
    "inspector_id_last4": 8744,
    "unit": 229304973450
}
```

**暗号化されたフィールドの組み合わせに対して一致検索を実行する**  
`inspector_id_last4.unit` の完全一致検索のために `UnitInspection` データベースをクエリする場合は、まず `inspector_id_last4` と `unit` のフィールドについての個別の標準ビーコンを作成します。その後、2 つの標準ビーコンから複合ビーコンを作成します。  
複合ビーコンを設定した後、複合ビーコンをパーティションキーとして指定するセカンダリインデックスを作成します。このセカンダリインデックスを使用して、`inspector_id_last4.unit` の完全一致検索のためにクエリを実行します。例えば、このビーコンをクエリして、インスペクターが特定のユニットについて実行した検査のリストを検索できます。

**暗号化されたフィールドの組み合わせに対して複雑なクエリを実行する**  
`inspector_id_last4` と `inspector_id_last4.unit` のために `UnitInspection` データベースをクエリする場合は、まず `inspector_id_last4` と `unit` のフィールドについて個別の標準ビーコンを作成します。その後、2 つの標準ビーコンから複合ビーコンを作成します。  
複合ビーコンを設定した後、複合ビーコンをソートキーとして指定するセカンダリインデックスを作成します。このセカンダリインデックスを使用して、特定のインスペクターで始まるエントリや、特定のインスペクターによって検査された特定のユニット ID 範囲内のすべてのユニットのリストを検索するために `UnitInspection` データベースをクエリできます。`inspector_id_last4.unit` についての完全一致検索を実行することもできます。

複合ビーコンの設定については、「[複合ビーコンの設定](configure-beacons.md#config-compound-beacons)」を参照してください。

### 単一のインデックスで暗号化されたフィールドとプレーンテキストフィールドの組み合わせをクエリする
<a name="se-example4"></a>

単一のインデックスで暗号化されたフィールドとプレーンテキストフィールドの組み合わせをクエリする必要がある場合は、個々の標準ビーコンとプレーンテキストフィールドを組み合わせて単一のインデックスを形成する複合ビーコンを作成します。複合ビーコンの構築に使用されるプレーンテキストフィールドは、[暗号化アクション](concepts.md#crypt-actions)`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`で `SIGN_ONLY`または とマークする必要があります。

複合ビーコンを設定した後、複合ビーコンをパーティションキーとして指定するセカンダリインデックスを作成して完全一致クエリを実行したり、ソートキーを使用してより複雑なクエリを実行したりできます。複合ビーコンをソートキーとして指定するセカンダリインデックスは、完全一致クエリや、よりカスタマイズされた複雑なクエリを実行できます。

#### 例
<a name="example4"></a>

次の例では、生産施設の検査データを追跡する `UnitInspection` という名前のデータベースについて考えてみます。データベース内の各レコードには、`work_id`、`inspection_date`、`inspector_id_last4`、および `unit` と呼ばれるフィールドが含まれています。完全なインスペクター ID は 0～99,999,999 の数値です。ただし、データセットが統一的に分布するようにするために、`inspector_id_last4` はインスペクターの ID の下 4 桁のみを格納します。データベース内の各フィールドは、プライマリキー `work_id` によって識別されます。`inspector_id_last4` および `unit` フィールドは、[暗号化アクション](concepts.md#crypt-actions)で `ENCRYPT_AND_SIGN` とマークされます。

`UnitInspection` データベース内のプレーンテキストエントリの例を次に示します。

```
{
    "work_id": "1c7fcff3-6e74-41a8-b7f7-925dc039830b",
    "inspection_date": 2023-06-07,
    "inspector_id_last4": 8744,
    "unit": 229304973450
}
```

**フィールドの組み合わせに対して一致検索を実行する**  
特定の日付に特定のインスペクターによって実施された検査について `UnitInspection` データベースをクエリする場合は、まず `inspector_id_last4` フィールドについての標準ビーコンを作成します。`inspector_id_last4` フィールドは、[暗号化アクション](concepts.md#crypt-actions)で `ENCRYPT_AND_SIGN` とマークされます。すべての暗号化された部分には独自の標準ビーコンが必要です。`inspection_date` フィールドは `SIGN_ONLY` とマークされており、標準ビーコンは必要ありません。次に、`inspection_date` フィールドと `inspector_id_last4` 標準ビーコンから複合ビーコンを作成します。  
複合ビーコンを設定した後、複合ビーコンをパーティションキーとして指定するセカンダリインデックスを作成します。このセカンダリインデックスを使用して、特定のインスペクターおよび検査日に完全に一致するレコードを検索するために、データベースをクエリします。例えば、ID が `8744` で終わるインスペクターが特定の日に実施したすべての検査のリストを検索するために、データベースをクエリできます。

**フィールドの組み合わせに対して複雑なクエリを実行する**  
`inspection_date` の範囲内で実施される検査を検索するため、または `inspector_id_last4` もしくは `inspector_id_last4.unit` によって制約されている特定の `inspection_date` に対して実施される検査を検索するためにデータベースをクエリする場合は、まず、`inspector_id_last4` および `unit` フィールドについての個別の標準ビーコンを作成します。その後、プレーンテキスト `inspection_date` フィールドと 2 つの標準ビーコンから複合ビーコンを作成します。  
複合ビーコンを設定した後、複合ビーコンをソートキーとして指定するセカンダリインデックスを作成します。このセカンダリインデックスを使用して、特定のインスペクターが特定の日付に実施した検査を検索するためにクエリを実行します。例えば、同日に検査されたすべてのユニットのリストを取得するために、データベースをクエリできます。または、指定された検査期間中に特定のユニットに対して実行されたすべての検査のリストを取得するために、データベースをクエリできます。

複合ビーコンの設定については、「[複合ビーコンの設定](configure-beacons.md#config-compound-beacons)」を参照してください。

# ビーコンの長さの選択
<a name="choosing-beacon-length"></a>


****  

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

検索可能な暗号化用に設定された暗号化されたフィールドに新しい値を書き込むと、 AWS Database Encryption SDK はプレーンテキスト値で HMAC を計算します。この HMAC 出力は、そのフィールドのプレーンテキストの値と 1 対 1 (1:1) で一致します。HMAC 出力は切り詰められ、複数の個別のプレーンテキストの値が、切り詰められた同じ HMAC タグにマッピングされます。これらのコリジョン、つまり誤検知により、不正ユーザーは、プレーンテキストの値に関する特徴的な情報を識別しにくくなります。

各ビーコンについて生成される誤検知の平均数は、切り詰めた後に残っているビーコンの長さによって決まります。標準ビーコンを設定する場合、必要なのはビーコンの長さを定義することだけです。複合ビーコンは、その構築元となる標準ビーコンのビーコン長を使用します。

ビーコンはフィールドの暗号化状態を変更しません。ただし、ビーコンを使用する場合、クエリの効率性と、データの分布に関して明らかになる情報の量との間には、固有のトレードオフが存在します。

検索可能な暗号化の目標は、ビーコンを使用して暗号化されたデータをクエリすることにより、クライアント側の暗号化されたデータベースに関連するパフォーマンスコストを削減することです。ビーコンは、計算元の暗号化されたフィールドと一緒に格納されます。これは、データセットの分布に関する特徴的な情報を明らかにできることを意味します。極端な場合には、不正ユーザーが分布に関して明らかになった情報を分析し、それを使用してフィールドのプレーンテキストの値を特定できる可能性があります。ビーコンの長さを適切に選択すると、これらのリスクを軽減し、分布の機密性を維持するのに役立ちます。

脅威モデルを確認して、必要なセキュリティのレベルを決定します。例えば、データベースにアクセスできるが、プレーンテキストデータにはアクセスすべきではないユーザーが増えるほど、データセットの分布の機密性を保護する必要が高まる可能性があります。機密性を高めるには、ビーコンはより多くの誤検知を生成する必要があります。機密性が高まると、クエリのパフォーマンスが低下します。

**セキュリティとパフォーマンス**
+ ビーコンが**過度に長い**場合には、生成される誤検知が過度に少なくなるため、データセットの分布に関する特徴的な情報が明らかになる可能性があります。
+ ビーコンが**過度に短い**場合には、生成される誤検知が過度に多くなるため、データベースの広範なスキャンが必要になり、これに伴ってクエリのパフォーマンスコストが増加します。

ソリューションのために適切なビーコンの長さを決定する際には、クエリのパフォーマンスに必要以上に影響を及ぼすことなく、データのセキュリティを適切に維持できる長さを見つける必要があります。ビーコンによって維持されるセキュリティの量は、データセットの[分布](searchable-encryption.md#searchable-encryption-distribution)と、ビーコンの構築元となるフィールドの[相関関係](searchable-encryption.md#searchable-encryption-correlated-values)によって異なります。次のトピックは、ビーコンが統一的に分布しており、相関データが含まれていないことを前提としています。

**Topics**
+ [ビーコンの長さの計算](#calculate-beacon-length)
+ [例](#beacon-length-example)

## ビーコンの長さの計算
<a name="calculate-beacon-length"></a>

ビーコンの長さはビット単位で定義され、切り詰め後に保持される HMAC タグのビット数を指します。推奨されるビーコンの長さは、データセットの分布、相関値の存在、セキュリティとパフォーマンスに関する具体的な要件によって異なります。データセットが統一的に分布している場合は、実装に最適なビーコンの長さを特定するために、次の方程式と手順を役立てることができます。これらの方程式は、ビーコンが生成する誤検知の平均数を推定するだけであり、データセット内のすべての一意の値が特定の数の誤検知を生成することを保証するものではありません。

**注記**  
これらの方程式の有効性は、データセットの分布によって異なります。データセットが統一的に分布していない場合は、「[ビーコンが適しているデータセット](searchable-encryption.md#are-beacons-right-for-me)」を参照してください。  
一般に、データセットが統一的な分布から離れるほど、ビーコンを短くする必要があります。

1. 

   **母集団を推定する**

   母集団は、標準ビーコンの構築元となるフィールド内の一意の値の想定される数であり、フィールドに格納される値の想定される合計数ではありません。例えば、従業員のミーティングの場所を特定する暗号化された `Room` フィールドについて考えてみましょう。`Room` フィールドには合計 100,000 の値が格納されることが想定されますが、従業員がミーティングのために予約できる部屋は 50 室しかありません。これは、`Room` フィールドに格納できる一意の値が 50 個しかないため、母集団が 50 であることを意味します。
**注記**  
標準ビーコンの構築元が[仮想フィールド](beacons.md#virtual-field)である場合、ビーコンの長さを計算するために使用される母集団は、仮想フィールドによって作成された一意の組み合わせの数です。

   母集団を推定する際には、データセットの予測される増加を必ず考慮してください。ビーコンを持つ新しいレコードを書き込んだ後に、そのビーコンの長さを更新することはできません。脅威モデルと既存のデータベースソリューションを確認して、今後 5 年間にこのフィールドに格納されることが想定される一意の値の数の見積もりを作成します。

   母集団は正確である必要はありません。まず、現在のデータベース内の一意の値の数を特定するか、または最初の 1 年間に格納されることが想定される一意の値の数を見積もります。次に、以下の質問を使用して、今後 5 年間で予測される一意の値の増加を判断します。
   + 一意の値が 10 倍になることが想定されますか?
   + 一意の値が 100 倍になることが想定されますか?
   + 一意の値が 1,000 倍になることが想定されますか?

   一意の値が 50,000 個である場合と 60,000 個である場合の差は大きくなく、推奨されるビーコンの長さは両方とも同じです。しかし、一意の値が 50,000 個である場合と 500,000 個である場合、その差は、推奨されるビーコンの長さに大きく影響します。

   郵便番号や姓などの一般的なデータタイプの出現頻度について、公開データを確認することを検討してください。例えば、米国には 41,707 の郵便番号があります。使用する母集団は、独自のデータベースに比例する必要があります。データベース内の `ZIPCode` フィールドに米国全土のデータが含まれている場合は、`ZIPCode` フィールドに現在 41,707 個の一意の値がない場合でも、母集団を 41,707 と定義することが考えられます。データベース内の `ZIPCode` フィールドに 1 つの州のデータのみが含まれ、今後も 1 つの州のデータのみが含まれる場合は、母集団を 41,704 ではなく、その州の郵便番号の合計数として定義できます。

1. **想定されるコリジョン数の推奨範囲を計算する**

   特定のフィールドについての適切なビーコンの長さを決定するには、まず、想定されるコリジョン数の適切な範囲を特定する必要があります。想定されるコリジョン数は、特定の HMAC タグにマッピングされる一意のプレーンテキストの値の平均想定数を表します。1 つの一意のプレーンテキストの値について想定される誤検知の数は、想定されるコリジョン数より 1 少ない数となります。

   想定されるコリジョン数は 2 以上、かつ、母集団の平方根未満にすることをお勧めします。次の方程式は、母集団に 16 個以上の一意の値がある場合にのみ機能します。

   ```
   2 ≤ number of collisions < √(Population)
   ```

   コリジョン数が 2 未満の場合、ビーコンが生成する誤検知が過度に少なくなります。想定されるコリジョンの最小数として 2 が推奨されます。これは、平均して、フィールド内のすべての一意の値が、他の 1 つの一意の値にマッピングされることによって、少なくとも 1 つの誤検知を生成することを意味するためです。

1. **ビーコンの長さの推奨範囲を計算する**

   想定されるコリジョンの最小数と想定されるコリジョンの最大数を特定したら、次の方程式を使用して適切なビーコンの長さの範囲を特定します。

   ```
   number of collisions = Population * 2-(beacon length)
   ```

   まず、想定されるコリジョン数が 2 (想定されるコリジョンの推奨最小数) である場合の**ビーコンの長さ**を求めます。

   ```
   2 = Population * 2-(beacon length)
   ```

   その後、想定コリジョン数が母集団の平方根 (想定されるコリジョンの推奨最大数) である場合の**ビーコンの長さ**を求めます。

   ```
   √(Population) = Population * 2-(beacon length)
   ```

   この方程式によって生成される結果を切り捨ててビーコンの長さを算出します。例えば、方程式を解くとビーコンの長さが 15.6 になる場合、その値を 16 ビットになるように切り上げるのではなく、15 ビットになるように切り捨てることをお勧めします。

1. **ビーコンの長さを選択する**

   これらの方程式は、フィールドのビーコンの長さの推奨範囲を特定するだけです。データセットのセキュリティを維持するために、可能な場合は常に、ビーコンを短くすることをお勧めします。ただし、実際に使用するビーコンの長さは、脅威モデルによって決まります。脅威モデルを確認する際にパフォーマンス要件を考慮して、フィールドに最適なビーコンの長さを決定します。

   ビーコンを短くするとクエリのパフォーマンスが低下し、ビーコンを長くするとセキュリティが低下します。一般的に、データセットが不均一に[分布](searchable-encryption.md#searchable-encryption-distribution)している場合、または[相関](searchable-encryption.md#searchable-encryption-correlated-values)フィールドから個別のビーコンを構築する場合は、ビーコンをより短くして、データセットの分布に関して明らかになる情報の量を最小限に抑える必要があります。

   脅威モデルを確認し、フィールドの分布に関して明らかになる特徴的な情報がセキュリティ全体に脅威を与えるものではないと判断した場合は、計算した推奨範囲よりもビーコンを長くすることを選択することもできます。例えば、フィールドのビーコンの長さの推奨範囲を計算したところ、9～16 ビットと算出されたとしても、パフォーマンスの低下を避けるために 24 ビットのビーコン長を使用することを選択できます。

   ビーコンの長さは慎重に選択してください。ビーコンを持つ新しいレコードを書き込んだ後に、そのビーコンの長さを更新することはできません。

## 例
<a name="beacon-length-example"></a>

[暗号化アクション](concepts.md#crypt-actions)で `unit` フィールドを `ENCRYPT_AND_SIGN` としてマークしたデータベースを考えてみましょう。`unit` フィールドの標準ビーコンを設定するには、`unit` フィールドについて想定される誤検知の数とビーコンの長さを決定する必要があります。

1. 母集団を推定する

   脅威モデルと現在のデータベースソリューションを確認した結果、`unit` フィールドには最終的に 100,000 個の一意の値が存在することになると想定されます。

   つまり、**母集団 = 100,000** です。

1. 想定されるコリジョン数の推奨範囲を計算します。

   この例では、想定されるコリジョン数は 2～316 です。

   ```
   2 ≤ number of collisions < √(Population)
   ```

   1. 

      ```
      2 ≤ number of collisions < √(100,000)
      ```

   1. 

      ```
      2 ≤ number of collisions < 316
      ```

1. ビーコンの長さの推奨範囲を計算します。

   この例では、ビーコンの長さは 9～16 ビットである必要があります。

   ```
   number of collisions = Population * 2-(beacon length)
   ```

   1. 想定されるコリジョンの最小数が**ステップ 2** で特定された数である場合のビーコンの長さを計算します。

      ```
      2 = 100,000 * 2-(beacon length)
      ```

      ビーコンの長さ = 15.6、または 15 ビット

   1. 想定されるコリジョンの最大数が**ステップ 2** で特定された数である場合のビーコンの長さを計算します。

      ```
      316 = 100,000 * 2-(beacon length)
      ```

      ビーコンの長さ = 8.3、または 8 ビット

1. セキュリティとパフォーマンスの要件に適したビーコンの長さを決定します。

   15 未満のビットごとに、パフォーマンスコストとセキュリティが 2 倍になります。
   + 16 ビット
     + 平均すると、それぞれの一意の値は他の 1.5 個のユニットにマッピングされます。
     + セキュリティ: 切り詰められた同じ HMAC タグを持つ 2 つのレコードは、同じプレーンテキストの値を持つ可能性が 66% あります。
     + パフォーマンス: クエリは、実際にリクエストした 10 件のレコードごとに 15 件のレコードを取得します。
   + 14 ビット
     + 平均すると、それぞれの一意の値は他の 6.1 個のユニットにマッピングされます。
     + セキュリティ: 切り詰められた同じ HMAC タグを持つ 2 つのレコードは、同じプレーンテキストの値を持つ可能性が 33% あります。
     + パフォーマンス: クエリは、実際にリクエストした 10 件のレコードごとに 30 件のレコードを取得します。

# ビーコン名の選択
<a name="choosing-beacon-name"></a>


****  

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

すべてのビーコンは、一意のビーコン名によって識別されます。ビーコンが設定されると、ビーコン名は、暗号化されたフィールドをクエリする際に使用される名前となります。ビーコン名は、暗号化されたフィールドまたは[仮想フィールド](beacons.md#virtual-field)と同じ名前にすることができますが、暗号化されていないフィールドと同じ名前にすることはできません。2 つの異なるビーコンに同じビーコン名を付けることはできません。

ビーコンに名前を付けて設定する方法を示す例については、「[ビーコンの設定](configure-beacons.md)」を参照してください。



**標準ビーコンの命名**  
標準ビーコンに名前を付ける場合は、可能な場合は常に、ビーコン名を[ビーコンソース](beacons.md#beacon-source)に解決することを強くお勧めします。これは、ビーコン名と、標準ビーコンの構築元となる暗号化されたフィールドまたは[仮想](beacons.md#virtual-field)フィールドの名前が同じであることを意味します。例えば、`LastName` という名前の暗号化されたフィールドについての標準ビーコンを作成する場合、ビーコン名も `LastName` である必要があります。

ビーコン名がビーコンソースと同じ場合、設定からビーコンソースを省略できます。 AWS Database Encryption SDK は自動的にビーコン名をビーコンソースとして使用します。

# ビーコンの設定
<a name="configure-beacons"></a>


****  

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

検索可能な暗号化をサポートするビーコンには 2 つのタイプがあります。標準ビーコンは、一致検索を実行します。これらは、データベースで検索可能な暗号化を実装する最も簡単な方法です。複合ビーコンは、リテラルプレーンテキスト文字列と標準ビーコンを組み合わせて、より複雑なクエリを実行します。

ビーコンは、データが入力されていない新しいデータベースに実装されるように設計されています。既存のデータベースで設定されたビーコンは、データベースに書き込まれる新しいレコードのみをマッピングします。ビーコンはフィールドのプレーンテキストの値から計算されます。フィールドが暗号化されると、ビーコンは既存のデータをマッピングできなくなります。ビーコンを持つ新しいレコードを書き込んだ後に、そのビーコンの設定を更新することはできません。ただし、レコードに追加する新しいフィールドに新しいビーコンを追加できます。

アクセスパターンを決定したら、データベース実装の 2 番目のステップとしてビーコンを設定する必要があります。次に、すべてのビーコンを設定したら、[AWS KMS 階層キーリング](use-hierarchical-keyring.md)の作成、ビーコンバージョンの定義、[各ビーコンのセカンダリインデックスの設定](ddb-searchable-encryption.md#ddb-beacon-indexes)、[暗号化アクション](concepts.md#crypt-actions)の定義、データベースと AWS Database Encryption SDK クライアントの設定を行う必要があります。詳細については、「[ビーコンの使用](using-beacons.md)」を参照してください。

ビーコンのバージョンをより簡単に定義できるように、標準ビーコンと複合ビーコンのリストを作成することをお勧めします。作成した各ビーコンを、設定時にそれぞれの標準ビーコンリストまたは複合ビーコンリストに追加します。

**Topics**
+ [標準ビーコンの設定](#config-standard-beacons)
+ [複合ビーコンの設定](#config-compound-beacons)
+ [設定例](beacon-config-examples.md)

## 標準ビーコンの設定
<a name="config-standard-beacons"></a>

[標準ビーコン](beacons.md#standard-beacon-overview)は、データベースで検索可能な暗号化を実装する最も簡単な方法です。単一の暗号化されたフィールドまたは仮想フィールドについてのみ一致検索を実行できます。

### 設定構文の例
<a name="standard-config-syntax"></a>

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

```
List<StandardBeacon> standardBeaconList = new ArrayList<>();
StandardBeacon exampleStandardBeacon = StandardBeacon.builder()
    .name("beaconName")
    .length(beaconLengthInBits)
    .build();
standardBeaconList.add(exampleStandardBeacon);
```

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

```
var standardBeaconList = new List<StandardBeacon>();
StandardBeacon exampleStandardBeacon = new StandardBeacon
  {
    Name = "beaconName",
    Length = 10
  };
standardBeaconList.Add(exampleStandardBeacon);
```

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

```
let standard_beacon_list = vec![
    StandardBeacon::builder().name("beacon_name").length(beacon_length_in_bits).build()?,
```

------

標準ビーコンを設定するには、次の値を指定します。

**ビーコン名**  
暗号化されたフィールドをクエリする際に使用する名前。  
ビーコン名は、暗号化されたフィールドまたは仮想フィールドと同じ名前にすることができますが、暗号化されていないフィールドと同じ名前にすることはできません。可能な場合は常に、標準ビーコンの構築元となる暗号化されたフィールドまたは[仮想フィールド](beacons.md#virtual-field)の名前を使用することを強くお勧めします。2 つの異なるビーコンに同じビーコン名を付けることはできません。実装に最適なビーコン名を決定する方法については、「[ビーコン名の選択](choosing-beacon-name.md)」を参照してください。

**ビーコンの長さ**  
切り詰めた後に保持されるビーコンのハッシュ値のビット数。  
ビーコンの長さによって、特定のビーコンによって生成される誤検知の平均数が決まります。実装に適切なビーコンの長さを決定する方法の詳細とヘルプについては、「[ビーコンの長さの決定](choosing-beacon-length.md)」を参照してください。

**ビーコンソース (オプション)**  
標準ビーコンの構築元となるフィールド。  
ビーコンソースは、フィールド名、またはネストされたフィールドの値を参照するインデックスである必要があります。ビーコン名がビーコンソースと同じ場合、設定からビーコンソースを省略でき、 AWS Database Encryption SDK は自動的にビーコン名をビーコンソースとして使用します。

### 仮想フィールドの作成
<a name="create-virtual-field"></a>

[仮想フィールド](beacons.md#virtual-field)を作成するには、仮想フィールドの名前とソースフィールドのリストを指定する必要があります。ソースフィールドを仮想部分のリストに追加する順序によって、仮想フィールドを構築するためにこれらのソースフィールドが連結される順序が決まります。次の例では、2 つのソースフィールド全体を連結して、仮想フィールドを作成します。

**注記**  
データベースに入力する前に、仮想フィールドが期待される結果を生成することを確認することをお勧めします。詳細については、[「ビーコン出力のテスト](ddb-searchable-encryption.md#ddb-beacon-testing)」を参照してください。

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

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

```
List<VirtualPart> virtualPartList = new ArrayList<>();
    virtualPartList.add(sourceField1);
    virtualPartList.add(sourceField2);

VirtualField virtualFieldName = VirtualField.builder()
    .name("virtualFieldName")
    .parts(virtualPartList)
    .build();

List<VirtualField> virtualFieldList = new ArrayList<>();
    virtualFieldList.add(virtualFieldName);
```

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

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

```
var virtualPartList = new List<VirtualPart> { sourceField1, sourceField2 };

var virtualFieldName = new VirtualField
{
    Name = "virtualFieldName",
    Parts = virtualPartList
};

var virtualFieldList = new List<VirtualField> { virtualFieldName };
```

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

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

```
let virtual_part_list = vec![source_field_one, source_field_two];

let state_and_has_test_result_field = VirtualField::builder()
    .name("virtual_field_name")
    .parts(virtual_part_list)
    .build()?;

let virtual_field_list = vec![virtual_field_name];
```

------

ソースフィールドの特定のセグメントを使用して仮想フィールドを作成するには、ソースフィールドを仮想部分のリストに追加する前に、その変換を定義する必要があります。

#### 仮想フィールドのセキュリティに関する考慮事項
<a name="virtual-field-considerations"></a>

ビーコンはフィールドの暗号化状態を変更しません。ただし、ビーコンを使用する場合、クエリの効率性と、データの分布に関して明らかになる情報の量との間には、固有のトレードオフが存在します。ビーコンを設定する方法によって、そのビーコンによって維持されるセキュリティのレベルが決まります。

既存の標準ビーコンと重複するソースフィールドを含む仮想フィールドを作成しないようにしてください。標準ビーコンを作成するために既に使用されているソースフィールドを含む仮想フィールドを作成すると、両方のビーコンのセキュリティレベルが低下する可能性があります。セキュリティが低下する程度は、追加のソースフィールドによって追加されるエントロピーのレベルによって異なります。エントロピーのレベルは、追加のソースフィールド内の固有の値の分布と、追加のソースフィールドが仮想フィールドの全体的なサイズに寄与するビット数によって決まります。

母集団と[ビーコンの長さ](choosing-beacon-length.md)を使用して、仮想フィールドのソースフィールドがデータセットのセキュリティを維持するかどうかを判断できます。母集団は、フィールド内の一意の値の想定数です。母集団は正確である必要はありません。フィールドの母集団の推定については、「[母集団の推定](choosing-beacon-length.md#estimate-population)」を参照してください。

仮想フィールドのセキュリティを確認する際には、次の例を考慮してください。
+ Beacon1 は `FieldA` から構築されます。`FieldA` の母集団は、**2 (Beacon1 の長さ)** よりも大きいです。
+ Beacon2 は `VirtualField` から構築されます。これは、`FieldA`、`FieldB`、`FieldC`、および `FieldD` から構築されます。`FieldB`、`FieldC`、および `FieldD` を合わせると、母集団は **2N** よりも大きくなります

次のステートメントが真の場合、Beacon2 は Beacon1 と Beacon2 の両方のセキュリティを維持します。

```
N ≥ (Beacon1 length)/2
```

と

```
N ≥ (Beacon2 length)/2
```

### ビーコンスタイルの定義
<a name="define-beacon-styles"></a>

標準ビーコンを使用して、暗号化されたフィールドまたは仮想フィールドの等価検索を実行できます。または、複合ビーコンを構築して、より複雑なデータベースオペレーションを実行することもできます。標準ビーコンの整理と管理に役立つように、 AWS Database Encryption SDK には、標準ビーコンの用途を定義する以下のオプション*ビーコンスタイル*が用意されています。

**注記**  
ビーコンスタイルを定義するには、 AWS Database Encryption SDK のバージョン 3.2 以降を使用する必要があります。ビーコン設定にビーコンスタイルを追加する前に、すべてのリーダーに新しいバージョンをデプロイします。

------
#### [ PartOnly ]

として定義された標準ビーコンは、複合ビーコンの[暗号化された部分](#encrypted-parts)を定義するために`PartOnly`のみ使用できます。`PartOnly` 標準ビーコンを直接クエリすることはできません。

**Java**  

```
List<StandardBeacon> standardBeaconList = new ArrayList<>();
StandardBeacon exampleStandardBeacon = StandardBeacon.builder()
    .name("beaconName")
    .length(beaconLengthInBits)
    .style(
        BeaconStyle.builder()
           .partOnly(PartOnly.builder().build())
        .build()
    )
    .build();
standardBeaconList.add(exampleStandardBeacon);
```

**C\$1 / .NET**  

```
new StandardBeacon
{
    Name = "beaconName",
    Length = beaconLengthInBits,
    Style = new BeaconStyle
    {
        PartOnly = new PartOnly()
    }
}
```

**Rust**  

```
StandardBeacon::builder()
    .name("beacon_name")
    .length(beacon_length_in_bits)
    .style(BeaconStyle::PartOnly(PartOnly::builder().build()?))
    .build()?
```

------
#### [ Shared ]

デフォルトでは、すべての標準ビーコンはビーコン計算用の一意の HMAC キーを生成します。そのため、2 つの異なる標準ビーコンから暗号化されたフィールドに対して等価検索を実行することはできません。として定義された標準ビーコン`Shared`は、別の標準ビーコンの HMAC キーを計算に使用します。

たとえば、`beacon1`フィールドと`beacon2`フィールドを比較する必要がある場合は、 を、 の計算に の HMAC キーを使用する`Shared`ビーコン`beacon2`として定義`beacon1`します。

**注記**  
`Shared` ビーコンを設定する前に、セキュリティとパフォーマンスのニーズを考慮してください。 `Shared` ビーコンは、データセットの分布に関して識別できる統計情報の量を増やす可能性があります。たとえば、どの共有フィールドに同じプレーンテキスト値が含まれているかを明らかにすることができます。

**Java**  

```
List<StandardBeacon> standardBeaconList = new ArrayList<>();
StandardBeacon exampleStandardBeacon = StandardBeacon.builder()
    .name("beacon2")
    .length(beaconLengthInBits)
    .style(
        BeaconStyle.builder()
           .shared(Shared.builder().other("beacon1").build())
        .build()
    )
    .build();
standardBeaconList.add(exampleStandardBeacon);
```

**C\$1 / .NET**  

```
new StandardBeacon
{
    Name = "beacon2",
    Length = beaconLengthInBits,
    Style = new BeaconStyle
    {
        Shared = new Shared { Other = "beacon1" }
    }
}
```

**Rust**  

```
StandardBeacon::builder()
    .name("beacon2")
    .length(beacon_length_in_bits)
    .style(BeaconStyle::Shared(
       Shared::builder().other("beacon1").build()?,
    ))
    .build()?
```

------
#### [ AsSet ]

デフォルトでは、フィールド値がセットの場合、 AWS Database Encryption SDK はセットの単一の標準ビーコンを計算します。そのため、 が暗号化されたフィールド`CONTAINS(a, :value)``a`であるクエリを実行することはできません。として定義された標準ビーコンは、セットの各要素の個々の標準ビーコン値を`AsSet`計算し、ビーコン値をセットとして項目に保存します。これにより、 AWS Database Encryption SDK はクエリ を実行できます`CONTAINS(a, :value)`。

`AsSet` 標準ビーコンを定義するには、セット内の要素が同じビーコン[の長さ](choosing-beacon-length.md)を使用できるように、同じ母集団の要素である必要があります。ビーコン値の計算時に衝突が発生した場合、ビーコンセットの要素数がプレーンテキストセットよりも少なくなる可能性があります。

**注記**  
`AsSet` ビーコンを設定する前に、セキュリティとパフォーマンスのニーズを考慮してください。 `AsSet` ビーコンは、データセットの分布に関して識別できる統計情報の量を増やす可能性があります。たとえば、プレーンテキストセットのサイズが明らかになる場合があります。

**Java**  

```
List<StandardBeacon> standardBeaconList = new ArrayList<>();
StandardBeacon exampleStandardBeacon = StandardBeacon.builder()
    .name("beaconName")
    .length(beaconLengthInBits)
    .style(
        BeaconStyle.builder()
           .asSet(AsSet.builder().build())
        .build()
    )
    .build();
standardBeaconList.add(exampleStandardBeacon);
```

**C\$1 / .NET**  

```
new StandardBeacon
{
    Name = "beaconName",
    Length = beaconLengthInBits,
    Style = new BeaconStyle
    {
        AsSet = new AsSet()
    }
}
```

**Rust**  

```
StandardBeacon::builder()
    .name("beacon_name")
    .length(beacon_length_in_bits)
    .style(BeaconStyle::AsSet(AsSet::builder().build()?))
    .build()?
```

------
#### [ SharedSet ]

として定義された標準ビーコンは、 関数`Shared`と `AsSet`関数`SharedSet`を組み合わせて、セットとフィールドの暗号化された値に対して等価検索を実行できるようにします。これにより、 AWS Database Encryption SDK は、 `CONTAINS(a, b)` `a`が暗号化されたセットであり、 が暗号化されたフィールド`b`であるクエリを実行できます。

**注記**  
`Shared` ビーコンを設定する前に、セキュリティとパフォーマンスのニーズを考慮してください。 `SharedSet` ビーコンは、データセットの分布に関して識別できる統計情報の量を増やす可能性があります。たとえば、プレーンテキストセットのサイズや、同じプレーンテキスト値を含む共有フィールドが明らかになる場合があります。

**Java**  

```
List<StandardBeacon> standardBeaconList = new ArrayList<>();
StandardBeacon exampleStandardBeacon = StandardBeacon.builder()
    .name("beacon2")
    .length(beaconLengthInBits)
    .style(
        BeaconStyle.builder()
           .sharedSet(SharedSet.builder().other("beacon1").build())
        .build()
    )
    .build();
standardBeaconList.add(exampleStandardBeacon);
```

**C\$1 / .NET**  

```
new StandardBeacon
{
    Name = "beacon2",
    Length = beaconLengthInBits,
    Style = new BeaconStyle
    {
        SharedSet = new SharedSet { Other = "beacon1" }
    }
}
```

**Rust**  

```
StandardBeacon::builder()
    .name("beacon2")
    .length(beacon_length_in_bits)
    .style(BeaconStyle::SharedSet(
        SharedSet::builder().other("beacon1").build()?,
    ))
    .build()?
```

------

## 複合ビーコンの設定
<a name="config-compound-beacons"></a>

複合ビーコンは、リテラルプレーンテキスト文字列と標準ビーコンを組み合わせて、単一のインデックスから 2 つの異なるレコードタイプをクエリしたり、ソートキーを使用してフィールドの組み合わせをクエリしたりするなど、複雑なデータベースオペレーションを実行します。複合ビーコンは、`ENCRYPT_AND_SIGN`、、`SIGN_ONLY`および `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`フィールドから構築できます。複合ビーコンに含まれる暗号化されたフィールドごとに標準ビーコンを作成する必要があります。

**注記**  
データベースに入力する前に、複合ビーコンが期待される結果を生成することを確認することをお勧めします。詳細については、[「ビーコン出力のテスト](ddb-searchable-encryption.md#ddb-beacon-testing)」を参照してください。

### 設定構文の例
<a name="compound-config-syntax"></a>

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

**複合ビーコン設定**

次の例では、複合ビーコン設定内で暗号化および署名されたパートリストをローカルに定義します。

```
List<CompoundBeacon> compoundBeaconList = new ArrayList<>();
CompoundBeacon exampleCompoundBeacon = CompoundBeacon.builder()
    .name("compoundBeaconName")
    .split(".")
    .encrypted(encryptedPartList) 
    .signed(signedPartList)                       
    .constructors(constructorList) 
    .build();
compoundBeaconList.add(exampleCompoundBeacon);
```

**ビーコンバージョン定義**

次の例では、ビーコンバージョンで暗号化および署名されたパートリストをグローバルに定義します。ビーコンバージョンの定義の詳細については、[「ビーコンの使用](using-beacons.md)」を参照してください。

```
 List<BeaconVersion> beaconVersions = new ArrayList<>();
beaconVersions.add(
    BeaconVersion.builder()
        .standardBeacons(standardBeaconList)
        .compoundBeacons(compoundBeaconList)
        .encryptedParts(encryptedPartList)
        .signedParts(signedPartList)
        .version(1) // MUST be 1
        .keyStore(keyStore)
        .keySource(BeaconKeySource.builder()
            .single(SingleKeyStore.builder()
                .keyId(branchKeyId)
                .cacheTTL(6000)
                .build())
            .build())
        .build()
);
```

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

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

**複合ビーコン設定**

次の例では、複合ビーコン設定内で暗号化および署名されたパートリストをローカルに定義します。

```
var compoundBeaconList = new List<CompoundBeacon>();       
var exampleCompoundBeacon = new CompoundBeacon
 {
    Name = "compoundBeaconName",
    Split = ".",
    Encrypted = encryptedPartList,
    Signed = signedPartList,                        
    Constructors = constructorList 
 };
compoundBeaconList.Add(exampleCompoundBeacon);
```

**ビーコンバージョン定義**

次の例では、ビーコンバージョンで暗号化および署名されたパートリストをグローバルに定義します。ビーコンバージョンの定義の詳細については、[「ビーコンの使用](using-beacons.md)」を参照してください。

```
var beaconVersions = new List<BeaconVersion>
{
    new BeaconVersion
    {
        StandardBeacons = standardBeaconList,
        CompoundBeacons = compoundBeaconList,
        EncryptedParts = encryptedPartsList,
        SignedParts = signedPartsList,
        Version = 1, // MUST be 1
        KeyStore = keyStore,
        KeySource = new BeaconKeySource
        {
            Single = new SingleKeyStore
            {
                KeyId = branchKeyId,
                CacheTTL = 6000
            }
        }
    }
};
```

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

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

**複合ビーコン設定**

次の例では、複合ビーコン設定内で暗号化および署名されたパートリストをローカルに定義します。

```
let compound_beacon_list = vec![
    CompoundBeacon::builder()
        .name("compound_beacon_name")
        .split(".")
        .encrypted(encrypted_parts_list)
        .signed(signed_parts_list)
        .constructors(constructor_list)
        .build()?
```

**ビーコンバージョン定義**

次の例では、ビーコンバージョンで暗号化および署名されたパートリストをグローバルに定義します。ビーコンバージョンの定義の詳細については、[「ビーコンの使用](using-beacons.md)」を参照してください。

```
let beacon_versions = BeaconVersion::builder()
    .standard_beacons(standard_beacon_list)
    .compound_beacons(compound_beacon_list)
    .encrypted_parts(encrypted_parts_list)
    .signed_parts(signed_parts_list)
    .version(1) // MUST be 1
    .key_store(key_store.clone())
    .key_source(BeaconKeySource::Single(
        SingleKeyStore::builder()
            .key_id(branch_key_id)
            .cache_ttl(6000)
            .build()?,
    ))
    .build()?;
let beacon_versions = vec![beacon_versions];
```

------

[暗号化されたパート](#encrypted-parts)と[署名されたパート](#signed-parts)は、ローカルまたはグローバルに定義されたリストで定義できます。可能な限り[、ビーコンバージョンの](using-beacons.md#beacon-version)グローバルリストで暗号化および署名されたパートを定義することをお勧めします。暗号化されたパートと署名されたパートをグローバルに定義することで、各パートを 1 回定義し、そのパートを複数の複合ビーコン設定で再利用できます。暗号化または署名されたパートを 1 回だけ使用する場合は、複合ビーコン設定のローカルリストで定義できます。[コンストラクタリスト](#constructor-parts)では、ローカルパートとグローバルパートの両方を参照できます。

暗号化および署名されたパートリストをグローバルに定義する場合は、複合ビーコンが複合ビーコン設定のフィールドをアセンブルできるすべての方法を識別するコンストラクタパートのリストを指定する必要があります。

**注記**  
暗号化および署名されたパートリストをグローバルに定義するには、バージョン 3.2 以降の AWS Database Encryption SDK を使用する必要があります。新しいパートをグローバルに定義する前に、すべてのリーダーに新しいバージョンをデプロイします。  
既存のビーコン設定を更新して、暗号化および署名されたパートリストをグローバルに定義することはできません。

複合ビーコンを設定するには、次の値を指定します。

**ビーコン名**  
暗号化されたフィールドをクエリする際に使用する名前。  
ビーコン名は、暗号化されたフィールドまたは仮想フィールドと同じ名前にすることができますが、暗号化されていないフィールドと同じ名前にすることはできません。2 つのビーコンを同じ名前にすることはできません。実装に最適なビーコン名を決定する方法については、「[ビーコン名の選択](choosing-beacon-name.md)」を参照してください。

**分割文字**  
複合ビーコンを設定する部分を分離するために使用される文字。  
分割文字は、複合ビーコンの構築元となるフィールドのプレーンテキストの値に出現することはできません。

**暗号化されたパートリスト**  
複合ビーコンに含まれる `ENCRYPT_AND_SIGN` フィールドを識別します。  
各部分には、名前とプレフィックスが含まれている必要があります。部分の名前は、暗号化されたフィールドから構築された標準ビーコンの名前である必要があります。プレフィックスには任意の文字列を指定できますが、一意である必要があります。暗号化された部分は、署名付きの部分と同じプレフィックスを持つことはできません。複合ビーコンによって提供される部分と他の部分を区別する短い値を使用することをお勧めします。  
可能な限り、暗号化されたパートをグローバルに定義することをお勧めします。1 つの複合ビーコンでのみ使用する場合は、暗号化された部分をローカルで定義することを検討してください。ローカルに定義された暗号化されたパートは、グローバルに定義された暗号化されたパートと同じプレフィックスまたは名前を持つことはできません。  

```
List<EncryptedPart> encryptedPartList = new ArrayList<>();
EncryptedPart encryptedPartExample = EncryptedPart.builder()
    .name("standardBeaconName")
    .prefix("E-")
    .build();
encryptedPartList.add(encryptedPartExample);
```

```
var encryptedPartList = new List<EncryptedPart>();
var encryptedPartExample = new EncryptedPart
 {
    Name = "compoundBeaconName",
    Prefix = "E-"
 };
encryptedPartList.Add(encryptedPartExample);
```

```
let encrypted_parts_list = vec![
    EncryptedPart::builder()
        .name("standard_beacon_name")
        .prefix("E-")
        .build()?
];
```

**署名付きパートリスト**  
複合ビーコンに含まれる署名付きフィールドを識別します。  
署名付きパートはオプションです。署名付きパートを参照しない複合ビーコンを設定できます。
各部分には、名前、ソース、プレフィックスが含まれている必要があります。ソースは、パートが識別する `SIGN_ONLY`または `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`フィールドです。ソースは、フィールド名、またはネストされたフィールドの値を参照するインデックスである必要があります。パーツ名がソースを識別する場合、ソースを省略すると、 AWS Database Encryption SDK は自動的にその名前をソースとして使用します。可能な場合は常に、部分名としてソースを指定することをお勧めします。プレフィックスには任意の文字列を指定できますが、一意である必要があります。署名付きの部分は、暗号化された部分と同じプレフィックスを持つことはできません。複合ビーコンによって提供される部分と他の部分を区別する短い値を使用することをお勧めします。  
可能な限り、署名付きパートをグローバルに定義することをお勧めします。署名付きパートを 1 つの複合ビーコンでのみ使用する場合は、ローカルで定義することを検討してください。ローカルに定義された署名付きパートは、グローバルに定義された署名付きパートと同じプレフィックスまたは名前を持つことはできません。  

```
List<SignedPart> signedPartList = new ArrayList<>();
SignedPart signedPartExample = SignedPart.builder()
    .name("signedFieldName")
    .prefix("S-")
    .build();
signedPartList.add(signedPartExample);
```

```
var signedPartsList = new List<SignedPart>
{
    new SignedPart { Name = "signedFieldName1", Prefix = "S-" },
    new SignedPart { Name = "signedFieldName2", Prefix = "SF-" }
};
```

```
let signed_parts_list = vec![
    SignedPart::builder()
        .name("signed_field_name_1")
        .prefix("S-")
        .build()?,
   SignedPart::builder()
        .name("signed_field_name_2")
        .prefix("SF-")
        .build()?,     
];
```

**コンストラクタリスト**  
暗号化および署名付きの部分を複合ビーコンによってアセンブルするさまざまな方法を定義するコンストラクターを識別します。コンストラクタリストでは、ローカルパートとグローバルパートの両方を参照できます。  
グローバルに定義された暗号化および署名された部分から複合ビーコンを構築する場合は、コンストラクタリストを指定する必要があります。  
グローバルに定義された暗号化または署名されたパートを使用して複合ビーコンを構築しない場合、コンストラクタリストはオプションです。コンストラクタリストを指定しない場合、 AWS Database Encryption SDK は次のデフォルトのコンストラクタを使用して複合ビーコンをアセンブルします。  
+ すべての署名付きの部分 (署名付きの部分のリストに追加された順)
+ 暗号化されたすべての部分 (暗号化された部分のリストに追加された順)
+ すべての部分は必須です  
**コンストラクタ**  
各コンストラクターは、複合ビーコンをアセンブルする 1 つの方法を定義するコンストラクター部分の順序付きリストです。コンストラクター部分はリストに追加された順序で結合され、各部分は指定された分割文字で区切られます。  
各コンストラクター部分は、暗号化された部分または署名付きの部分に名前を付け、その部分がコンストラクター内で必須であるか、またはオプションであるかを定義します。例えば、`Field1`、`Field1.Field2`、および `Field1.Field2.Field3` で複合ビーコンをクエリする場合は、`Field2` および `Field3` をオプションとしてマークし、コンストラクターを 1 つ作成します。  
各コンストラクターには、少なくとも 1 つの必須部分が必要です。クエリで `BEGINS_WITH` 演算子を使用できるように、各コンストラクターの最初の部分を必須にすることをお勧めします。  
コンストラクターは、必要な部分がすべてレコード内に存在する場合に成功します。新しいレコードを書き込む際に、複合ビーコンはコンストラクターのリストを使用して、指定された値からビーコンをアセンブルできるかどうかを判断します。コンストラクターがコンストラクターのリストに追加された順序でビーコンのアセンブルを試み、成功した最初のコンストラクターを使用します。コンストラクターが成功しない場合、ビーコンはレコードに書き込まれません。  
すべてのリーダーとライターは、クエリの結果が確実に正しくなるようにコンストラクターの同じ順序を指定する必要があります。
独自のコンストラクターのリストを指定するには、次の手順を使用します。  

1. 暗号化部分と署名付きの部分ごとにコンストラクター部分を作成し、その部分が必須かどうかを定義します。

   コンストラクター部分の名前は、標準ビーコンの名前、またはそれが表す署名されたフィールドの名前である必要があります。

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

   ```
   ConstructorPart field1ConstructorPart = ConstructorPart.builder()
           .name("Field1")
           .required(true)
           .build();
   ```

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

   ```
   var field1ConstructorPart = new ConstructorPart { Name = "Field1", Required = true };
   ```

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

   ```
   let field_1_constructor_part = ConstructorPart::builder()
       .name("field_1")
       .required(true)
       .build()?;
   ```

------

1. **ステップ 1** で作成したコンストラクター部分を使用して、複合ビーコンをアセンブルする可能な方法ごとにコンストラクターを作成します。

   例えば、`Field1.Field2.Field3` と `Field4.Field2.Field3` をクエリする場合は、2 つのコンストラクターを作成する必要があります。`Field1` と `Field4` は、2 つの別個のコンストラクターで定義されているため、両方とも必須にすることができます。

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

   ```
   // Create a list for Field1.Field2.Field3 queries
   List<ConstructorPart> field123ConstructorPartList = new ArrayList<>();
   field123ConstructorPartList.add(field1ConstructorPart);
   field123ConstructorPartList.add(field2ConstructorPart);
   field123ConstructorPartList.add(field3ConstructorPart);
   Constructor field123Constructor = Constructor.builder()
           .parts(field123ConstructorPartList)
           .build();
   // Create a list for Field4.Field2.Field1 queries
   List<ConstructorPart> field421ConstructorPartList = new ArrayList<>();
   field421ConstructorPartList.add(field4ConstructorPart);
   field421ConstructorPartList.add(field2ConstructorPart);
   field421ConstructorPartList.add(field1ConstructorPart);
   Constructor field421Constructor = Constructor.builder()
           .parts(field421ConstructorPartList)
           .build();
   ```

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

   ```
   // Create a list for Field1.Field2.Field3 queries
    var field123ConstructorPartList = new Constructor
   {
       Parts = new List<ConstructorPart> { field1ConstructorPart, field2ConstructorPart, field3ConstructorPart }
   };
   // Create a list for Field4.Field2.Field1 queries        
   var field421ConstructorPartList = new Constructor
   {
       Parts = new List<ConstructorPart> { field4ConstructorPart, field2ConstructorPart, field1ConstructorPart }
   };
   ```

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

   ```
   // Create a list for field1.field2.field3 queries
   let field1_field2_field3_constructor = Constructor::builder()
       .parts(vec![
           field1_constructor_part,
           field2_constroctor_part.clone(),
           field3_constructor_part,
       ])
       .build()?;
   
   // Create a list for field4.field2.field1 queries
   let field4_field2_field1_constructor = Constructor::builder()
       .parts(vec![
           field4_constructor_part,
           field2_constroctor_part.clone(),
           field1_constructor_part,
       ])
       .build()?;
   ```

------

1. **ステップ 2** で作成したすべてのコンストラクターを含むコンストラクターのリストを作成します。

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

   ```
   List<Constructor> constructorList = new ArrayList<>();
   constructorList.add(field123Constructor);
   constructorList.add(field421Constructor);
   ```

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

   ```
   var constructorList = new List<Constructor>
   {
       field123Constructor,
       field421Constructor
   };
   ```

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

   ```
   let constructor_list = vec![
       field1_field2_field3_constructor,
       field4_field2_field1_constructor,
   ];
   ```

------

1. 複合ビーコンを作成する`constructorList`ときに を指定します。

# 設定例
<a name="beacon-config-examples"></a>


****  

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

次の例は、標準ビーコンと複合ビーコンを設定する方法を示しています。次の設定は、ビーコンの長さを指定しません。設定用に適切なビーコンの長さを決定する方法については、「[ビーコンの長さを選択する](choosing-beacon-length.md)」を参照してください。

ビーコンの設定方法と使用方法を示す完全なコード例については、GitHub の aws-database-encryption-sdk-dynamodb リポジトリにある [Java](https://github.com/aws/aws-database-encryption-sdk-dynamodb//tree/main/Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/searchableencryption)、[.NET](https://github.com/aws/aws-database-encryption-sdk-dynamodb/tree/main/Examples/runtimes/net/src/searchableencryption/)、および [Rust](https://github.com/aws/aws-database-encryption-sdk-dynamodb/blob/main/releases/rust/db_esdk/examples/searchableencryption/) の検索可能な暗号化の例を参照してください。

**Topics**
+ [標準ビーコン](#standard-config-examples)
+ [複合ビーコン](#compound-config-examples)

## 標準ビーコン
<a name="standard-config-examples"></a>

完全一致を検索するために `inspector_id_last4` フィールドをクエリする場合は、次の設定を使用して標準ビーコンを作成します。

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

```
List<StandardBeacon> standardBeaconList = new ArrayList<>();
StandardBeacon exampleStandardBeacon = StandardBeacon.builder()
    .name("inspector_id_last4")
    .length(beaconLengthInBits)
    .build();
standardBeaconList.add(exampleStandardBeacon);
```

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

```
var standardBeaconList = new List<StandardBeacon>>);
StandardBeacon exampleStandardBeacon = new StandardBeacon
  {
    Name = "inspector_id_last4",
    Length = 10
  };
standardBeaconList.Add(exampleStandardBeacon);
```

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

```
let last4_beacon = StandardBeacon::builder()
    .name("inspector_id_last4")
    .length(10)
    .build()?;
                        
let unit_beacon = StandardBeacon::builder().name("unit").length(30).build()?;

let standard_beacon_list = vec![last4_beacon, unit_beacon];
```

------

## 複合ビーコン
<a name="compound-config-examples"></a>

`inspector_id_last4` および `inspector_id_last4.unit` で `UnitInspection` データベースをクエリする場合は、次の設定で複合ビーコンを作成します。この複合ビーコンには[暗号化された部分](configure-beacons.md#encrypted-parts)のみが必要です。

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

```
// 1. Create standard beacons for the inspector_id_last4 and unit fields.
List<StandardBeacon> standardBeaconList = new ArrayList<>();
StandardBeacon inspectorBeacon = StandardBeacon.builder()
    .name("inspector_id_last4")
    .length(beaconLengthInBits)
    .build();
standardBeaconList.add(inspectorBeacon);

StandardBeacon unitBeacon = StandardBeacon.builder()
    .name("unit")
    .length(beaconLengthInBits)
    .build();
standardBeaconList.add(unitBeacon);        

// 2. Define the encrypted parts.
List<EncryptedPart> encryptedPartList = new ArrayList<>();

// Each encrypted part needs a name and prefix
// The name must be the name of the standard beacon
// The prefix must be unique
// For this example we use the prefix "I-" for "inspector_id_last4"
// and "U-" for "unit"
EncryptedPart encryptedPartInspector = EncryptedPart.builder()
    .name("inspector_id_last4")
    .prefix("I-")
    .build();
encryptedPartList.add(encryptedPartInspector);

EncryptedPart encryptedPartUnit = EncryptedPart.builder()
    .name("unit")
    .prefix("U-")
    .build();
encryptedPartList.add(encryptedPartUnit);   

// 3. Create the compound beacon.
// This compound beacon only requires a name, split character, 
// and list of encrypted parts
CompoundBeacon inspectorUnitBeacon = CompoundBeacon.builder()
    .name("inspectorUnitBeacon")
    .split(".")
    .sensitive(encryptedPartList)
    .build();
```

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

```
// 1. Create standard beacons for the inspector_id_last4 and unit fields.
StandardBeacon inspectorBeacon = new StandardBeacon
 {
   Name = "inspector_id_last4",
   Length = 10
 };
standardBeaconList.Add(inspectorBeacon);
StandardBeacon unitBeacon = new StandardBeacon
 {
    Name = "unit",
    Length = 30
 };  
standardBeaconList.Add(unitBeacon);
                
// 2. Define the encrypted parts.
var last4EncryptedPart = new EncryptedPart

// Each encrypted part needs a name and prefix
// The name must be the name of the standard beacon
// The prefix must be unique
// For this example we use the prefix "I-" for "inspector_id_last4"
// and "U-" for "unit"
var last4EncryptedPart = new EncryptedPart
 {
   Name = "inspector_id_last4",
   Prefix = "I-"
 };
encryptedPartList.Add(last4EncryptedPart);

var unitEncryptedPart = new EncryptedPart
 {
   Name = "unit",
   Prefix = "U-"
 };
encryptedPartList.Add(unitEncryptedPart); 

// 3. Create the compound beacon.
// This compound beacon only requires a name, split character, 
// and list of encrypted parts
var compoundBeaconList = new List<CompoundBeacon>>);
var inspectorCompoundBeacon = new CompoundBeacon
  {
      Name = "inspector_id_last4",
      Split = ".",
      Encrypted = encryptedPartList
  };
compoundBeaconList.Add(inspectorCompoundBeacon);
```

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

```
// 1. Create standard beacons for the inspector_id_last4 and unit fields.
let last4_beacon = StandardBeacon::builder()
    .name("inspector_id_last4")
    .length(10)
    .build()?;
                        
let unit_beacon = StandardBeacon::builder().name("unit").length(30).build()?;

let standard_beacon_list = vec![last4_beacon, unit_beacon];
                        
// 2. Define the encrypted parts.
// The name must be the name of the standard beacon
// The prefix must be unique
// For this example we use the prefix "I-" for "inspector_id_last4"
// and "U-" for "unit"
let encrypted_parts_list = vec![
    EncryptedPart::builder()
        .name("inspector_id_last4")
        .prefix("I-")
        .build()?,
    EncryptedPart::builder().name("unit").prefix("U-").build()?,
];

// 3. Create the compound beacon
// This compound beacon only requires a name, split character, 
// and list of encrypted parts
let compound_beacon_list = vec![CompoundBeacon::builder()
    .name("last4UnitCompound")
    .split(".")
    .encrypted(encrypted_parts_list)
    .build()?];
```

------

# ビーコンの使用
<a name="using-beacons"></a>


****  

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

ビーコンを使用すると、クエリ対象のデータベース全体を復号することなく、暗号化されたレコードを検索できます。ビーコンは、データが入力されていない新しいデータベースに実装されるように設計されています。既存のデータベースで設定されたビーコンは、データベースに書き込まれる新しいレコードのみをマッピングします。ビーコンはフィールドのプレーンテキストの値から計算されます。フィールドが暗号化されると、ビーコンは既存のデータをマッピングできなくなります。ビーコンを持つ新しいレコードを書き込んだ後に、そのビーコンの設定を更新することはできません。ただし、レコードに追加する新しいフィールドに新しいビーコンを追加できます。

ビーコンを設定した後、データベースにデータを入力し、ビーコンをクエリする前に、次のステップを完了する必要があります。

1. ** AWS KMS 階層キーリングを作成する**

   検索可能な暗号化を使用するには、[AWS KMS 階層キーリング](use-hierarchical-keyring.md)を使用して、レコードを保護するために使用される[データキー](concepts.md#data-key)を生成、暗号化、および復号する必要があります。

   ビーコンを設定した後、[階層キーリング](use-hierarchical-keyring.md#hierarchical-keyring-prereqs)の前提条件をアセンブルし、[階層キーリングを作成](use-hierarchical-keyring.md#initialize-hierarchical-keyring)します。

   階層キーリングが必要な理由の詳細については、「[検索可能な暗号化のための階層キーリングの使用](use-hierarchical-keyring.md#searchable-encryption-hierarchical-keyrings)」を参照してください。

1. 

   **ビーコンのバージョンを定義する**

   `keyStore`、`keySource`、設定したすべての標準ビーコンのリスト、設定したすべての複合ビーコンのリスト、暗号化されたパートのリスト、署名されたパートのリスト、ビーコンバージョンを指定します。ビーコンのバージョンとして `1` を指定する必要があります。`keySource` の定義に関するガイダンスについては、「[ビーコンキーソースの定義](use-hierarchical-keyring.md#beacon-key-source)」を参照してください。

   次の Java の例では、シングルテナンシーデータベースのビーコンバージョンを定義します。マルチテナンシーデータベースのビーコンバージョンの定義については、「[マルチテナンシーデータベースの検索可能な暗号化](searchable-encryption-multitenant.md)」を参照してください。

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

   ```
    List<BeaconVersion> beaconVersions = new ArrayList<>();
   beaconVersions.add(
       BeaconVersion.builder()
           .standardBeacons(standardBeaconList)
           .compoundBeacons(compoundBeaconList)
           .encryptedParts(encryptedPartsList)
           .signedParts(signedPartsList)
           .version(1) // MUST be 1
           .keyStore(keyStore)
           .keySource(BeaconKeySource.builder()
               .single(SingleKeyStore.builder()
                   .keyId(branchKeyId)
                   .cacheTTL(6000)
                   .build())
               .build())
           .build()
   );
   ```

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

   ```
   var beaconVersions = new List<BeaconVersion>
   {
       new BeaconVersion
       {
           StandardBeacons = standardBeaconList,
           CompoundBeacons = compoundBeaconList,
           EncryptedParts = encryptedPartsList,
           SignedParts = signedPartsList,
           Version = 1, // MUST be 1
           KeyStore = branchKeyStoreName,
           KeySource = new BeaconKeySource
           {
               Single = new SingleKeyStore
               {
                   KeyId = branch-key-id,
                   CacheTTL = 6000
               }
           }
       }
   };
   ```

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

   ```
   let beacon_version = BeaconVersion::builder()
       .standard_beacons(standard_beacon_list)
       .compound_beacons(compound_beacon_list)
       .version(1) // MUST be 1
       .key_store(key_store.clone())
       .key_source(BeaconKeySource::Single(
           SingleKeyStore::builder()
               // `keyId` references a beacon key.
               // For every branch key we create in the keystore,
               // we also create a beacon key.
               // This beacon key is not the same as the branch key,
               // but is created with the same ID as the branch key.
               .key_id(branch_key_id)
               .cache_ttl(6000)
               .build()?,
       ))
       .build()?;
   let beacon_versions = vec![beacon_version];
   ```

------

1. **セカンダリインデックスを設定する**

   [ビーコンを設定](configure-beacons.md)した後、暗号化されたフィールドを検索する前に、各ビーコンを反映するセカンダリインデックスを設定する必要があります。詳細については、「[ビーコンを使用したセカンダリインデックスの設定](ddb-searchable-encryption.md#ddb-beacon-indexes)」を参照してください。

1. **[暗号化アクション](concepts.md#crypt-actions)を定義する**

   標準ビーコンの構築に使用されるすべてのフィールドを `ENCRYPT_AND_SIGN` とマークする必要があります。ビーコンの構築に使用される他のすべてのフィールドは、 `SIGN_ONLY`または とマークする必要があります`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`。

1. ** AWS Database Encryption SDK クライアントを設定する**

   DynamoDB テーブルのテーブル項目を保護する AWS Database Encryption SDK クライアントを設定するには、[DynamoDB の Java クライアント側の暗号化ライブラリ](ddb-java.md)」を参照してください。

## ビーコンのクエリ
<a name="querying-beacons"></a>

設定するビーコンのタイプによって、実行できるクエリのタイプが決まります。標準ビーコンは、フィルター式を使用して一致検索を実行します。複合ビーコンは、リテラルプレーンテキスト文字列と標準ビーコンを組み合わせて、複雑なクエリを実行します。暗号化されたデータをクエリする際には、ビーコン名で検索します。

2 つの標準ビーコンの値は、基になる同じプレーンテキストが含まれている場合でも比較できません。2 つの標準ビーコンは、同じプレーンテキストの値について 2 つの異なる HMAC タグを生成します。その結果、標準ビーコンは次のクエリを実行できません。
+ `beacon1 = beacon2`
+ `beacon1 IN (beacon2)`
+ `value IN (beacon1, beacon2, ...)`
+ `CONTAINS(beacon1, beacon2)`

複合ビーコンは次のクエリを実行できます。
+ `BEGINS_WITH(a)`。ここで、`a` は、アセンブルされた複合ビーコンの先頭のフィールドの値全体を反映します。`BEGINS_WITH` 演算子を使用して、特定の部分文字列で始まる値を識別することはできません。ただし、`BEGINS_WITH(S_)` を使用することはできます。ここで、`S_` は、アセンブルされた複合ビーコンの先頭の部分のプレフィックスを反映します。
+ `CONTAINS(a)`。ここで、`a` は、アセンブルされた複合ビーコンが含むフィールドの値全体を反映します。`CONTAINS` 演算子を使用して、セット内の特定の部分文字列または値を含むレコードを識別することはできません。

  例えば、クエリ `CONTAINS(path, "a"` を実行することはできません。ここで、`a` は、セット内の値を反映します。
+ 複合ビーコンの[署名付きの部分](configure-beacons.md#signed-parts)を比較できます。署名付きの部分を比較する場合、必要に応じて、[暗号化部分](configure-beacons.md#encrypted-parts)のプレフィックスを 1 つ以上の署名付きの部分に付加できますが、暗号化されたフィールドの値をクエリに含めることはできません。

  例えば、署名付きの部分を比較し、`signedField1 = signedField2` または `value IN (signedField1, signedField2, ...)` をクエリできます。

  署名付きの部分と暗号化部分のプレフィックスを、`signedField1.A_ = signedField2.B_` に対するクエリによって比較することもできます。
+ `field BETWEEN a AND b`。ここで、`a` と `b` は署名付きの部分です。必要に応じて、暗号化部分のプレフィックスを 1 つ以上の署名付きの部分に付加できますが、暗号化されたフィールドの値をクエリに含めることはできません。

複合ビーコンに対するクエリに含める各部分のプレフィックスを含める必要があります。例えば、`encryptedField` および `signedField` の 2 つのフィールドから複合ビーコン `compoundBeacon` を構築した場合、ビーコンをクエリする際に、これらの 2 つの部分について設定されたプレフィックスを含める必要があります。

```
compoundBeacon = E_encryptedFieldValue.S_signedFieldValue
```

# マルチテナンシーデータベースの検索可能な暗号化
<a name="searchable-encryption-multitenant"></a>


****  

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

データベースで検索可能な暗号化を実装するには、[AWS KMS 階層キーリング](use-hierarchical-keyring.md)を使用する必要があります。 AWS KMS 階層キーリングは、レコードの保護に使用されるデータキーを生成、暗号化、復号します。また、ビーコンを生成するために使用されるビーコンキーも作成します。マルチテナントデータベースで AWS KMS 階層キーリングを使用する場合、テナントごとに個別のブランチキーとビーコンキーがあります。マルチテナンシーデータベース内の暗号化されたデータをクエリするには、クエリしているビーコンを生成するために使用されたビーコンキーマテリアルを特定する必要があります。詳細については、「[検索可能な暗号化のための階層キーリングの使用](use-hierarchical-keyring.md#searchable-encryption-hierarchical-keyrings)」を参照してください。

マルチテナンシーデータベースの[ビーコンバージョン](using-beacons.md#beacon-version)を定義する場合は、設定したすべての標準ビーコンのリスト、設定したすべての複合ビーコンのリスト、ビーコンバージョン、および `keySource` を指定します。[ビーコンキーソースを `MultiKeyStore` として定義](use-hierarchical-keyring.md#beacon-key-source)し、`keyFieldName`、ローカルビーコンキーキャッシュのキャッシュ Time To Live、およびローカルビーコンキーキャッシュの最大キャッシュサイズを含める必要があります。

[署名付きビーコン](configure.md#signed-beacons)を設定した場合は、それらを `compoundBeaconList` に含める必要があります。署名付きビーコンは、 `SIGN_ONLY`フィールドと `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`フィールドに対してインデックスを作成し、複雑なクエリを実行する複合ビーコンの一種です。

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

```
List<BeaconVersion> beaconVersions = new ArrayList<>();
    beaconVersions.add(
        BeaconVersion.builder()
                .standardBeacons(standardBeaconList)
                .compoundBeacons(compoundBeaconList)
                .version(1) // MUST be 1
                .keyStore(branchKeyStoreName)
                .keySource(BeaconKeySource.builder()
                        .multi(MultiKeyStore.builder()
                                .keyFieldName(keyField)
                                .cacheTTL(6000)
                                .maxCacheSize(10)
                        .build())
                .build())
        .build()
    );
```

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

```
var beaconVersions = new List<BeaconVersion>
{
    new BeaconVersion
    {
        StandardBeacons = standardBeaconList,
        CompoundBeacons = compoundBeaconList,
        EncryptedParts = encryptedPartsList,
        SignedParts = signedPartsList,
        Version = 1, // MUST be 1
        KeyStore = branchKeyStoreName,
        KeySource = new BeaconKeySource
        {
            Multi = new MultiKeyStore
            {
                KeyId = branch-key-id,
                CacheTTL = 6000,
                MaxCacheSize = 10
            }
        }
    }
};
```

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

```
let beacon_version = BeaconVersion::builder()
    .standard_beacons(standard_beacon_list)
    .compound_beacons(compound_beacon_list)
    .version(1) // MUST be 1
    .key_store(key_store.clone())
    .key_source(BeaconKeySource::Multi(
        MultiKeyStore::builder()
            // `keyId` references a beacon key.
            // For every branch key we create in the keystore,
            // we also create a beacon key.
            // This beacon key is not the same as the branch key,
            // but is created with the same ID as the branch key.
            .key_id(branch_key_id)
            .cache_ttl(6000)
            .max_cache_size(10)
            .build()?,
    ))
    .build()?;
let beacon_versions = vec![beacon_version];
```

------

**keyFieldName**  
[`keyFieldName`](use-hierarchical-keyring.md#keyFieldName) は、特定のテナンシーについて生成されたビーコンに使用されるビーコンキーに関連付けられた `branch-key-id` を格納するフィールドの名前を定義します。  
新しいレコードをデータベースに書き込むと、そのレコードについてのビーコンを生成するために使用されるビーコンキーを識別する `branch-key-id` がこのフィールドに格納されます。  
デフォルトでは、`keyField` はデータベースに明示的に格納されない概念的なフィールドです。 AWS Database Encryption SDK は、[マテリアルの説明](concepts.md#material-description)で暗号化された[データキー](concepts.md#data-key)`branch-key-id`から を識別し、複合ビーコンと[署名](configure.md#signed-beacons)付きビーコンで参照`keyField`できるように概念に値を保存します。マテリアルの説明は署名されているため、概念的な `keyField` は署名付きの部分とみなされます。  
暗号化アクション`keyField`に を `SIGN_ONLY`または `SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`フィールドとして含めて、 フィールドをデータベースに明示的に保存することもできます。これを実行するには、データベースにレコードを書き込むたびに、`branch-key-id` を手動で `keyField` に含める必要があります。

## マルチテナンシーデータベース内のビーコンのクエリ
<a name="query-multitenant-beacons"></a>

ビーコンをクエリするには、クエリに `keyField` を含めて、ビーコンの再計算に必要となる適切なビーコンキーマテリアルを識別する必要があります。レコードのビーコンを生成するために使用されるビーコンキーに関連付けられた `branch-key-id` を指定する必要があります。ブランチキー ID サプライヤーのテナンシーの `branch-key-id` を識別する[フレンドリ名](use-hierarchical-keyring.md#branch-key-id-supplier)を指定することはできません。次の方法でクエリに `keyField` を含めることができます。

**複合ビーコン**  
`keyField` をレコードに明示的に格納するかどうかにかかわらず、複合ビーコンに署名付きの部分として `keyField` を直接含めることができます。`keyField` の署名付きの部分は必須である必要があります。  
例えば、`encryptedField` および `signedField` の 2 つのフィールドから複合ビーコン `compoundBeacon` を構築する場合は、署名付きの部分として `keyField` も含める必要があります。これにより、`compoundBeacon` に対して次のクエリを実行できるようになります。  

```
compoundBeacon = E_encryptedFieldValue.S_signedFieldValue.K_branch-key-id
```

**署名付きビーコン**  
 AWS Database Encryption SDK は、標準ビーコンと複合ビーコンを使用して、検索可能な暗号化ソリューションを提供します。これらのビーコンには、少なくとも 1 つの暗号化されたフィールドが含まれている必要があります。ただし、 AWS Database Encryption SDK は、プレーンテキスト`SIGN_ONLY`と`SIGN_AND_INCLUDE_IN_ENCRYPTION_CONTEXT`フィールドから完全に設定できる[署名付きビーコン](configure.md#signed-beacons)もサポートしています。  
署名付きビーコンは単一の部分から構築できます。`keyField` をレコードに明示的に格納するかどうかにかかわらず、`keyField` から署名付きビーコンを構築し、それを使用して、`keyField` 署名付きビーコンに対するクエリと、他のビーコンの 1 つに対するクエリを組み合わせる複合クエリを作成できます。例えば、次のクエリを実行できます。  

```
keyField = K_branch-key-id AND compoundBeacon = E_encryptedFieldValue.S_signedFieldValue
```
署名付きビーコンの設定については、「[署名付きビーコンの作成](configure.md#signed-beacons)」を参照してください

**`keyField` に対する直接的なクエリの実行**  
暗号化アクションで `keyField` を指定し、そのフィールドをレコードに明示的に格納した場合は、ビーコンに対するクエリと、`keyField` に対するクエリを組み合わせた複合クエリを作成できます。標準ビーコンをクエリする場合は、`keyField` に対して直接クエリを実行することを選択できます。例えば、次のクエリを実行できます。  

```
keyField = branch-key-id AND standardBeacon = S_standardBeaconValue
```