Docs Menu
Docs Home
/
MongoDBマニュアル
/ / / / /

フィールドの暗号化とクエリ可能性

項目一覧

  • Overview
  • クエリを有効にする際の考慮事項
  • 暗号化するフィールドを指定する
  • クエリのフィールドの設定
  • 競合
  • 競合係数の調整
  • クエリ タイプ
  • クライアントとサーバー スキーマ
  • Queryable Encryption の有効化

次の Queryable Encryption に関するトピックについて学びます。

  • 暗号化されたフィールドでクエリを有効にする際の考慮事項。

  • 暗号化のフィールドを指定する方法。

  • 暗号化されたフィールドをクエリ可能にするように構成する方法。

  • クエリのタイプと暗号化されたフィールドで使用できるタイプ。

  • 暗号化されたフィールドでクエリパフォーマンスを最適化する方法。

Queryable Encryption を使用する場合、暗号化されたフィールドをクエリ可能にするかどうかを選択できます。 暗号化されたフィールドをクエリする必要がある CRUD 操作を実行する必要がない場合は、そのフィールドでクエリを有効にする必要がない場合があります。 You can still retrieve the entire document by querying other fields that are queryable or not encrypted.

暗号化されたフィールドをクエリ可能にすると、Queryable Encryption は暗号化されたフィールドごとにインデックスを作成します。これにより、そのフィールドの書込み操作が長くなる可能性があります。 書込み (write) 操作によってインデックス付きフィールドがアップデートされると、MongoDB は関連するインデックスもアップデートします。

暗号化されたコレクションを作成すると、MongoDB は2 つのメタデータのコレクションを作成し、ストレージ容量の必要量を増やします。

Queryable Encryption では、JSON 暗号化スキーマを使用して、MongoDB ドキュメント内のどのフィールドを自動的に暗号化するフィールドを指定します。 暗号化スキーマは、どのフィールドが暗号化され、それらのフィールドでどのクエリが使用できるかを定義します。

重要

暗号化には、 _idフィールドを除く任意のフィールドを指定できます。

暗号化とクエリのフィールドを指定するには、次のプロパティを含む暗号化スキーマを作成します。

キー名
タイプ
必須
path
文字列
必須
bsonType
文字列
必須
keyId
バイナリ

必須。 各フィールドのキー値を指定します。

注意

createEncryptedCollection()を呼び出し、 keyId: nullを設定すると、MongoDB ドライバーによってデータキーが自動的に作成されます。 次に、 createEncryptedCollectionは新しいkeyId値を持つ新しい暗号化スキームを返します。

queries
オブジェクト
任意。 フィールドをクエリ可能にするために含めます。

この例では、暗号化スキーマの作成方法を示します。

個人を特定できる情報(PII)、クレジットカード情報、機密性の高い医療情報が含まれている次のドキュメントを検討してみましょう。

{
"firstName": "Jon",
"lastName": "Snow",
"patientId": 12345187,
"address": "123 Cherry Ave",
"medications": [
"Adderall",
"Lipitor"
],
"patientInfo": {
"ssn": "921-12-1234",
"billing": {
"type": "visa",
"number": "1234-1234-1234-1234"
}
}
}

PII と機密医療情報を安全に保つには、暗号化スキーマを作成し、それらのフィールドを自動暗号化用に構成します。 事前に、暗号化されたフィールドごとに一意のキーを生成する必要があります。 例:

const encryptedFieldsObject = {
fields: [
{
path: "patientId",
keyId: "<unique data encryption key>",
bsonType: "int"
},
{
path: "patientInfo.ssn",
keyId: "<unique data encryption key>",
bsonType: "string"
},
{
path: "medications",
keyId: "<unique data encryption key>",
bsonType: "array"
},
{
path: "patientInfo.billing",
keyId: "<unique data encryption key>",
bsonType: "object"
}
]
}

クライアントでAutoEncryptionSettingsを構成し、 createEncryptedCollection()ヘルパー メソッドを使用してコレクションを作成します。

フィールドをクエリ可能にするには、フィールドにqueriesプロパティを含めます。 これにより、承認されたクライアントは、それらのフィールドに対して読み取りおよび書込みクエリを発行できるようになります。 queriesプロパティを省略すると、クライアントはフィールドをクエリできなくなります。

queries前のサンプル スキーマに プロパティを追加して、 フィールドとpatientId patientInfo.ssnフィールドをクエリ可能にします。

const encryptedFieldsObject = {
fields: [
{
path: "patientId",
bsonType: "int",
queries: { queryType: "equality" }
},
{
path: "patientInfo.ssn",
bsonType: "string",
queries: { queryType: "equality" }
},
{
path: "medications",
bsonType: "array"
},
{
path: "patientInfo.billing",
bsonType: "object"
},
]
}

同じフィールドと値のペアを連続して複数のドキュメントに挿入するなどの同時書込み操作では、競合(競合)が発生し、操作が遅延する可能性があります。

Queryable Encryption を使用すると、MongoDB は内部カウンターを使用して、暗号化されたコレクション内の各フィールドと値のペアの発生を追跡します。 競合係数は、配列のようにこのカウンターを分割します。 これにより、 insertupdate 、またはfindAndModifyを使用して、同じフィールドと値のペアが連続して含まれる暗号化されたフィールドを追加または変更するときに、カウンターの増加に関する問題を最小限に抑えられます。 contention = 0は、インデックス0に 1 つの要素を含む配列を作成します。 contention = 4はインデックス0 - 4に5要素を含む配列を作成します。 MongoDB は、挿入中にランダムな配列要素を増加させます。

設定されていない場合、 contentionはデフォルトで8になり、ほとんどのワークロードで高パフォーマンスが提供されます。 コンテンツが大きいと、濃度の低いフィールドで挿入およびアップデート操作のパフォーマンスは向上しますが、検索パフォーマンスは低下します。

オプションで、クエリ可能なフィールドにcontentionプロパティを含めて、競合係数のデフォルト値8を変更できます。 競合係数を変更する前に、次の点を考慮してください。

フィールドで同時書込み操作が頻繁に実行される場合にのみ、デフォルト値8より大きいcontentionを増やすことを検討してください。 競合値が高いと、挿入およびアップデート操作が優先される代わりに検索パフォーマンスが低下するため、ほとんど更新されることのないフィールドの競合係数が高い場合の利点は制約を超える可能性はありません。

フィールドが頻繁にクエリされるが、ほとんど書込まれない場合は、 contentionを減らすことを検討してください。 この場合、書込みおよび更新のパフォーマンスよりも検索パフォーマンスの方が優先されます。

以下の式を使用して、フィールドの競合係数を計算できます。

妥当な競合係数cfは、次の式の結果を最も近い正の整数に切り捨てた値です。

· (ω − 1)) / 0.2

たとえば、 30ミリ秒以内にフィールドで100の同時書込み操作がある場合、 ω = 100になります。 そのフィールドに50の最近の一意の値がある場合、 ω = 100/50 = 2になります。 これによりcf = (2·1)/0.2 = 10が返されます。

警告

フィールドと値のペアの頻度(濃度)など、データ自体のプロパティに競合係数を設定しないでください。 競合係数はワークロードに基づいてのみ設定します。

ω = 100valinserts = 1000が、 ω = 100/1000 = 0.1 ≈ 1cf = (1·0)/0.2 = 0 ≈ 1になる場合を考えてみましょう。 値の20は非常に頻繁に表示されるため、代わりにcontention = 3を設定します。 複数のデータベース スナップショットにアクセスする攻撃者は、 設定が高いほどフィールドと値のペアが頻繁にあることを推測できます。 この場合、 contentionを設定せずにデフォルトを8に設定すると、攻撃者はその情報を保持できなくなります。

競合とその暗号化への影響に関する詳細な情報については、MongoDB の Queryable Encryptionに関するドキュメントの「セクション9 : ガイドライン」を参照してください。

暗号化されたフィールド オブジェクトのqueriesオプションにクエリタイプを渡すと、フィールドに許可されたクエリタイプが設定されます。 サポートされているクエリタイプを使用して、暗号化されていないフィールドまたは暗号化されたフィールドをクエリすると、暗号化されたデータが返され、クライアントで復号化されます。

Queryable Encryption は現在、 noneequalityクエリタイプをサポートしています。 クエリタイプが指定されていない場合、デフォルトはnoneになります。 クエリタイプがnoneの場合、フィールドは暗号化されますが、クライアントはそのフィールドをクエリできません。

equalityクエリタイプは次の式をサポートしています。

注意

暗号化されたフィールドをnullまたは正規表現と比較するクエリでは、サポートされているクエリ演算子であってもエラーが発生します。

Queryable Encryption equalityクエリでは、暗号化されたフィールドが次のBSONタイプのいずれかと比較される場合、フィールドに対する読み取りまたは書込み操作はサポートされていません。

  • double

  • decimal128

  • object

  • array

MongoDB は、コレクション内の特定のフィールドの暗号化を強制するために、スキーマ検証を使用することをサポートしています。 自動 Queryable Encryption を使用するクライアントは、データベース接続構成に応じて特定の動作をします。

  • 接続encryptedFieldsMapオブジェクトに指定されたコレクションのキーが含まれている場合、クライアントは、リモート スキーマを使用するのではなく、そのオブジェクトを使用して自動 Queryable Encryption を実行します。 ローカル ルールは、少なくとも、リモート スキーマが暗号化が必要とマークするフィールドを暗号化する必要があります。

  • 接続encryptedFieldsMapオブジェクトに指定されたコレクションのキーが含まれていない場合、クライアントはコレクションのサーバー側リモート スキーマをダウンロードし、それを使用して自動 Queryable Encryption を実行します。

    重要

    動作に関する考慮事項

    クライアントが指定コレクションの暗号化スキーマを持っていない場合、次の状況が発生します。

    • クライアントは、サーバーが自動 Queryable Encryption に関する有効なスキーマを持っていることを信頼します。

    • クライアントはリモート スキーマを使用して自動 Queryable Encryption のみを実行します。 クライアントは、スキーマで指定された他の検証ルールを強制しません。

自動 Queryable Encryption の詳細については、次のリソースを参照してください。

コレクションを作成する前に、Queryable Encryption を有効にします。 コレクションの作成後に Queryable Encryption を有効にしても、そのコレクション内のドキュメントのフィールドは暗号化されません。 次の 2 つの方法のいずれかの方法で、フィールドで Queryable Encryption を有効にできます。

  • アプリケーションがコレクションを作成するために使用するクライアントに、 encryptedFieldsObject定数で表される暗号化スキーマを渡します。

const client = new MongoClient(uri, {
autoEncryption: {
keyVaultNameSpace: "<your keyvault namespace>",
kmsProviders: "<your kms provider>",
extraOptions: {
cryptSharedLibPath: "<path to Automatic Encryption Shared Library>"
},
encryptedFieldsMap: {
"<databaseName.collectionName>": { encryptedFieldsObject }
}
}
...
await client.db("<database name>").createCollection("<collection name>");
}

autoEncryption構成オプションの詳細については、「 Queryable Encryption の MongoClient オプション 」のセクションを参照してください。

  • 暗号化されたフィールド オブジェクトをcreateCollection()に渡して新しいコレクションを作成します。

await encryptedDB.createCollection("<collection name>", {
encryptedFields: encryptedFieldsObject
});

Tip

コレクションを作成するとき、およびコレクションにアクセスするためのクライアントを作成するときに暗号化されたフィールドを指定します。 これにより、サーバーのセキュリティが侵害された場合でも、クライアントを介して情報は暗号化されます。

重要

挿入操作で暗黙的にコレクションを作成するのではなく、明示的にコレクションを作成します。 createCollection()を使用してコレクションを作成すると、MongoDB は暗号化されたフィールドにインデックスを作成します。 このインデックスがないと、暗号化されたフィールドに対するクエリの実行が遅くなる可能性があります。

戻る

Fundamentals