Docs Menu
Docs Home
/ /

チュートリアル: Mongooseを使用したQueryable Encryption

このガイドでは、 Mongooseを使用して MongoDB のQueryable Encryption機能を実装するアプリケーションを作成する方法を学習できます。

Queryable Encryption を使用すると、ドキュメントフィールドを自動的に暗号化および復号化できます。 Queryable Encryption を使用して、アプリケーション内の 機密データ を暗号化し、データフィールドをサーバーに保存し、暗号化されたフィールドをクエリします。このチュートリアルでは、データ処理用の ODM(Object Document Mapper、オブジェクト ドキュメント マッパー)ライブラリを提供するMongooseを使用して、 Queryable Encryption を設定する方法を説明します。

このチュートリアルを開始する前に、次の前提条件タスクを完了してください。

  • MongoDB Atlasアカウントを作成し、クラスターを構成します。クラスターがMongoDB Serverバージョン7.0 以降で実行されていることを確認します。詳しくは、 MongoDB の使用開始ガイドをご覧ください。

  • 自動暗号化共有ライブラリをダウンロードします。手順を表示するには、「 クエリ分析コンポーネントのインストールと構成 」ガイドを参照してください。次の手順では、 MongoDBダウンロード センター に移動し、ライブラリをダウンロードするために必要なフォームに入力する方法を示します。

  • Node.js v..16 201以降をインストールします。

このチュートリアルでは、 Mongooseを使用するQueryable Encryptionアプリケーションを作成する方法を説明します。アプリケーションは、医療レコードを暗号化および復号化し、暗号化された医療データをクエリします。

Tip

完全なアプリケーション

このチュートリアルの完全なサンプルアプリケーションを表示するには、GitHub の mongoose-qe-app フォルダーを参照してください。

このセクションの手順に従って、プロジェクトの依存関係のインストール、環境を構成し、アプリケーション構造を作成します。

1

プロジェクトを初期化し、必要な依存関係をインストールするには、ターミナルで次のコマンドを実行します。

mkdir mongoose-qe-app
cd mongoose-qe-app
npm init -y
npm pkg set main="queryable-encryption-tutorial.js"
npm pkg set type="module"
npm pkg set scripts.start="node queryable-encryption-tutorial.js"
npm i mongoose mongodb dotenv mongodb-client-encryption

これらのコマンドは mongoose-qe-appプロジェクトディレクトリを作成し、次の依存関係をインストールします。

2

プロジェクトルートで、.envファイルを作成し、次のコードを貼り付けます。

# MongoDB Connection URI and Shared Library Path
MONGODB_URI="<connection URI>"
SHARED_LIB_PATH="<Automatic Encryption Shared Library path>"
# AWS Credentials
AWS_ACCESS_KEY_ID="<Your AWS access key ID>"
AWS_SECRET_ACCESS_KEY="<Your AWS secret access key>"
AWS_KEY_REGION="<Your AWS key region>"
AWS_KEY_ARN="<Your AWS key ARN>"
# Azure Credentials
AZURE_TENANT_ID="<Your Azure tenant ID>"
AZURE_CLIENT_ID="<Your Azure client ID>"
AZURE_CLIENT_SECRET="<Your Azure client secret>"
AZURE_KEY_NAME="<Your Azure key name>"
AZURE_KEY_VERSION="<Your Azure key version>"
AZURE_KEY_VAULT_ENDPOINT="<Your Azure key vault endpoint>"
# GCP Credentials
GCP_EMAIL="<Your GCP email>"
GCP_PRIVATE_KEY="<Your GCP private key>"
GCP_PROJECT_ID="<Your GCP project ID>"
GCP_LOCATION="<Your GCP location>"
GCP_KEY_RING="<Your GCP key ring>"
GCP_KEY_NAME="<Your GCP key name>"
GCP_KEY_VERSION="<Your GCP key version>"
# KMIP Credentials
KMIP_KMS_ENDPOINT="<Endpoint for your KMIP KMS>"
KMIP_TLS_CA_FILE="<Full path to your KMIP certificate authority file>"
KMIP_TLS_CERT_FILE="<Full path to your client certificate file>"

<connection URI> プレースホルダーをクラスターに接続する接続 URI に置き換え、<Automatic Encryption Shared Library path> を自動暗号化共有ライブラリへの完全パスに置き換えます。ダウンロードしたパッケージ内で、パスが lib/mongo_crypt_v1.dylib にあることを確認します。

.env テンプレートにリストされている KMS(Key Management System)のいずれかを使用する場合は、対応するプレースホルダー値を置き換えます。それ以外の場合は、これらの値を割り当てずに、カスタマー マスター キーをローカルに保存できます。このアプリケーションは、ローカルの CMKファイルを作成します。

警告

ローカル CMK ストレージ

カスタマー マスター キーをローカルに保存する場合は、このアプリケーションを本番環境では使用しないでください。リモート KMS を使用しないと、暗号化のキーへの不正アクセスや、データの復号に必要なキーが失われるリスクがあります。

Tip

キー管理システム

3

mongoose-qe-appディレクトリに移動し、アプリケーションロジックを保存する queryable-encryption-tutorial.js という名前のファイルを作成します。次のコードをこのファイルに貼り付けます。

import 'dotenv/config';
import mongoose from 'mongoose';
import * as qeHelper from './queryable-encryption-helpers.js';
import { MongoClient, ClientEncryption } from 'mongodb';
async function runExample() {
// Paste initial application variables below
// Paste credential and options variables below
// Paste connection and client configuration below
// Paste data key creation code below
// Paste encryption schema below
// Paste the model below
// Paste connection code below
// Paste the insertion operation below
// Paste the encrypted query below
await connection.close();
console.log('Connection closed.');
}
runExample().catch(console.dir);

次に、queryable-encryption-helpers.js という名前のファイルを作成し、次のコードを貼り付けます。

import 'dotenv/config';
import { writeFileSync, readFileSync, existsSync } from 'fs';
import { randomBytes } from 'crypto';
export async function dropExistingDatabase(client, databaseName) {
const database = client.db(databaseName);
await database.dropDatabase();
}
// Paste helper methods below

このファイルには、アプリケーション用の dropExistingDatabase()ヘルパー関数が含まれています。このチュートリアルの今後のステップでは、ヘルパー関数を追加するように指示されます。

4

初期データベースと暗号化変数を指定するには、queryable-encryption-tutorial.jsファイルの runExample() 関数に次のコードを貼り付けます。

const kmsProviderName = '<KMS provider>';
const uri = process.env.MONGODB_URI; // Your connection URI
const keyVaultDatabaseName = 'encryption';
const keyVaultCollectionName = '__keyVault';
const keyVaultNamespace = `${keyVaultDatabaseName}.${keyVaultCollectionName}`;
const encryptedDatabaseName = 'medicalRecords';
const encryptedCollectionName = 'patients';

'<KMS provider>' プレースホルダーをキープロバイダーに置き換えます: 'aws''azure''gcp'、または 'kmip'カスタマー マスター キーをローカルに保存するには、この値を 'local' に設定します。

コードでは、次の変数に事前にデータが入力されています。

  • keyVaultDatabaseName - データ暗号化キー(DEK)を保存するMongoDBのデータベース。このチュートリアルでは、encryption データベースを使用します。

  • keyVaultCollectionName - DEK を保存するMongoDBのコレクション。コードでは、この変数を__keyVault に設定し、 ユーザーコレクションと区別するためにアンダースコアを先頭に付けます。

  • keyVaultNamespace - DEK を保存するMongoDB内の名前空間。この変数は、keyVaultDatabaseName 変数とkeyVaultCollectionName 変数をピリオドで区切った構成で構成されています。

  • encryptionDatabaseName - 暗号化されたデータを保存するMongoDBのデータベース。このチュートリアルでは、medicalRecords データベースを使用します。

  • encryptedCollectionName - 暗号化されたデータを保存するMongoDBのコレクション。このチュートリアルでは、patients コレクションを使用します。

プロジェクト構造を設定したら、このセクションの手順に従って、KMS プロバイダーの認証情報と暗号化オプションを設定します。

1

getKMSProviderCredentials() 関数を queryable-encryption-helpers.jsファイルに追加します。この関数は、キー管理システム プロバイダーの認証情報を検索します。または、KMS プロバイダーを使用しない場合はローカルの CMKファイルを作成します。

dropExistingDatabase() 関数の後に次のコードを貼り付けます。

export function getKMSProviderCredentials(kmsProviderName) {
let kmsProviders;
switch (kmsProviderName) {
case 'aws':
kmsProviders = {
aws: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID, // Your AWS access key ID
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, // Your AWS secret access key
},
};
return kmsProviders;
case 'azure':
kmsProviders = {
azure: {
tenantId: process.env.AZURE_TENANT_ID, // Your Azure tenant ID
clientId: process.env.AZURE_CLIENT_ID, // Your Azure client ID
clientSecret: process.env.AZURE_CLIENT_SECRET, // Your Azure client secret
},
};
return kmsProviders;
case 'gcp':
kmsProviders = {
gcp: {
email: process.env.GCP_EMAIL, // Your GCP email
privateKey: process.env.GCP_PRIVATE_KEY, // Your GCP private key
},
};
return kmsProviders;
case 'kmip':
kmsProviders = {
kmip: {
endpoint: process.env.KMIP_KMS_ENDPOINT, // Your KMIP KMS endpoint
},
};
return kmsProviders;
case 'local':
(function () {
if (!existsSync('./customer-master-key.txt')) {
try {
writeFileSync('customer-master-key.txt', randomBytes(96));
} catch (err) {
throw new Error(
`Unable to write Customer Master Key to file due to the following error: ${err}`
);
}
}
})();
try {
// WARNING: Do not use a local key file in a production application
const localMasterKey = readFileSync('./customer-master-key.txt');
if (localMasterKey.length !== 96) {
throw new Error(
'Expected the customer master key file to be 96 bytes.'
);
}
kmsProviders = {
local: {
key: localMasterKey,
},
};
} catch (err) {
throw new Error(
`Unable to read the Customer Master Key due to the following error: ${err}`
);
}
return kmsProviders;
default:
throw new Error(
`Unrecognized value for KMS provider name \'${kmsProviderName}\' encountered while retrieving KMS credentials.`
);
}
}

この getKMSProviderCredentials() 関数は、 AWS、 Azure、 GCP、 KMIP 、 ローカルキーストレージなどの複数の KMS プロバイダーをサポートしています。

2

getCustomerMasterKeyCredentials() 関数を queryable-encryption-helpers.jsファイルに追加します。この関数は、KMS プロバイダーに基づいてカスタマー マスター キーの認証情報を検索します。

getKMSProviderCredentials() 関数の後に次のコードを貼り付けます。

export function getCustomerMasterKeyCredentials(kmsProviderName) {
let customerMasterKeyCredentials;
switch (kmsProviderName) {
case 'aws':
customerMasterKeyCredentials = {
key: process.env.AWS_KEY_ARN, // Your AWS Key ARN
region: process.env.AWS_KEY_REGION, // Your AWS Key Region
};
return customerMasterKeyCredentials;
case 'azure':
customerMasterKeyCredentials = {
keyVaultEndpoint: process.env.AZURE_KEY_VAULT_ENDPOINT, // Your Azure Key Vault Endpoint
keyName: process.env.AZURE_KEY_NAME, // Your Azure Key Name
};
return customerMasterKeyCredentials;
case 'gcp':
customerMasterKeyCredentials = {
projectId: process.env.GCP_PROJECT_ID, // Your GCP Project ID
location: process.env.GCP_LOCATION, // Your GCP Key Location
keyRing: process.env.GCP_KEY_RING, // Your GCP Key Ring
keyName: process.env.GCP_KEY_NAME, // Your GCP Key Name
};
return customerMasterKeyCredentials;
case 'kmip':
case 'local':
customerMasterKeyCredentials = {};
return customerMasterKeyCredentials;
default:
throw new Error(
`Unrecognized value for KMS provider name \'${kmsProviderName}\' encountered while retrieving Customer Master Key credentials.`
);
}
}

この関数は、選択した KMS プロバイダーに対応するカスタマー マスター キー認証情報を構成します。

3

getAutoEncryptionOptions() 関数を queryable-encryption-helpers.jsファイルに追加します。この関数は、アプリケーションの自動暗号化オプションを構成します。

getCustomerMasterKeyCredentials() 関数の後に次のコードを貼り付けます。

export async function getAutoEncryptionOptions(
kmsProviderName,
keyVaultNamespace,
kmsProviders
) {
if (kmsProviderName === 'kmip') {
const tlsOptions = {
kmip: {
tlsCAFile: process.env.KMIP_TLS_CA_FILE, // Path to your TLS CA file
tlsCertificateKeyFile: process.env.KMIP_TLS_CERT_FILE, // Path to your TLS certificate key file
},
};
const extraOptions = {
cryptSharedLibPath: process.env.SHARED_LIB_PATH, // Path to your Automatic Encryption Shared Library
};
const autoEncryptionOptions = {
keyVaultNamespace,
kmsProviders,
extraOptions,
tlsOptions,
};
return autoEncryptionOptions;
} else {
const extraOptions = {
cryptSharedLibPath: process.env.SHARED_LIB_PATH, // Path to your Automatic Encryption Shared Library
};
const autoEncryptionOptions = {
keyVaultNamespace,
kmsProviders,
extraOptions,
};
return autoEncryptionOptions;
}
}
4

ヘルパー関数を定義したので、それらを使用してメインのアプリケーションファイルから認証情報にアクセスできるようになります。

queryable-encryption-tutorial.jsファイルに移動し、// Paste credential and options variables below コードコメントの後に次のコードを貼り付けます。

const kmsProviderCredentials =
qeHelper.getKMSProviderCredentials(kmsProviderName);
const customerMasterKeyCredentials =
qeHelper.getCustomerMasterKeyCredentials(kmsProviderName);
const autoEncryptionOptions = await qeHelper.getAutoEncryptionOptions(
kmsProviderName,
keyVaultNamespace,
kmsProviderCredentials
);

このコードでは、 Queryable Encryptionの構成に使用される KMS プロバイダー認証情報、カスタマー マスター キー認証情報、自動暗号化オプションを取得するためにヘルパー関数を呼び出します。

暗号化設定を構成した後、このセクションの手順に従って、 MongoDB接続を設定し、データキーを作成し、 暗号化されたスキーマの定義 を行います。

1

MongoDB接続とクライアントを設定するには、queryable-encryption-tutorial.jsファイルに移動し、// Paste connection and client configuration below コードコメントの後に次のコードを貼り付けます。

const connection = mongoose.createConnection();
const client = new MongoClient(uri);
const clientEncryption = new ClientEncryption(
client,
autoEncryptionOptions
);
await qeHelper.dropExistingDatabase(client, encryptedDatabaseName);
await qeHelper.dropExistingDatabase(client, keyVaultDatabaseName);

このコードでは、暗号化操作用のMongoose接続、キー管理用のMongoDBクライアント、データキーを作成するための ClientEncryptionインスタンスを作成します。また、既存のデータベースもすべて削除され、チュートリアルのクリーンな設定が維持されます。

2

必要なデータキーを作成するには、// Paste data key creation code below コードコメントの後に次のコードを貼り付けます。

const keyId1 = await clientEncryption.createDataKey(
kmsProviderName, {
masterKey: customerMasterKeyCredentials,
});
const keyId2 = await clientEncryption.createDataKey(
kmsProviderName, {
masterKey: customerMasterKeyCredentials,
});
const keyId3 = await clientEncryption.createDataKey(
kmsProviderName, {
masterKey: customerMasterKeyCredentials,
});

このコードでは、クライアントドキュメントのさまざまなフィールドを暗号化するために使用される 3 つのデータ暗号化キーが作成されます。各暗号化されたフィールドには独自のデータキーが必要です。

3

暗号化されたスキーマ定義を作成するには、// Paste encryption schema below コードコメントの後に次のコードを貼り付けます。

const patientSchema = new mongoose.Schema({
patientName: {
type: String,
required: true
},
patientId: {
type: Number,
required: true
},
patientRecord: {
ssn: {
type: String,
encrypt: {
keyId: keyId1,
queries: { queryType: 'equality' }
}
},
billing: {
type: {
type: String,
encrypt: {
keyId: keyId2,
}
},
number: {
type: String,
encrypt: {
keyId: keyId3
}
}
},
billAmount: Number
}
}, {
encryptionType: 'queryableEncryption',
collection: encryptedCollectionName
});

このスキーマは、patientsコレクション内のドキュメントの構造を定義し、次の暗号化されたフィールドを指定します。

  • patientRecord.ssn: 暗号化と等価クエリ用の構成

  • patientRecord.billing.type: 暗号化されていますが、クエリはできません

  • patientRecord.billing.number: 暗号化されていますが、クエリはできません

4

patientsコレクションを表すために Patient という名前の新しいモデルを作成し、モデルに暗号化スキーマを登録します。モデルを作成するには、// Paste the model below コードコメントの後に次のコードを貼り付けます。

const Patient = connection.model('Patient', patientSchema);

このコードでは、データベース操作を実行するときにフィールドの自動暗号化と復号化を処理するMongooseモデルが作成されます。

5

モデルを登録したら、// Paste connection code below コードコメントの後に次のコードを貼り付けてデータベース接続を確立できます。

await connection.openUri(uri, {
autoEncryption: autoEncryptionOptions,
dbName: encryptedDatabaseName
});

これにより、自動暗号化が有効になっている medicalRecords データベースへの接続が確立されます。

アプリケーションとデータベースの接続を構成したら、このセクションの手順に従って暗号化されたドキュメントの挿入とクエリを行います。

1

暗号化されたフィールドを持つドキュメントを挿入するには、queryable-encryption-tutorial.jsファイルに移動し、// Paste the insertion operation below コードコメントの後に次のコードを貼り付けます。

const patientDocument = {
patientName: 'Jon Doe',
patientId: 12345678,
patientRecord: {
ssn: '987-65-4320',
billing: {
type: 'Visa',
number: '4111111111111111',
},
billAmount: 1500,
},
};
const result = await Patient.create(patientDocument);
if (result) {
console.log('Successfully inserted the patient document.');
console.log('Document ID:', result._id);
}

Queryable Encryption は、ドキュメントをMongoDBに保存する前に、patientRecord.ssn フィールドと patientRecord.billing フィールドを自動的に暗号化します。

2

暗号化されたフィールドをクエリするには、// Paste the encrypted query below コードコメントの後に次のコードを貼り付けます。

const findResult = await Patient.findOne({
'patientRecord.ssn': '987-65-4320',
});
console.log('Found patient:');
console.log(findResult);

このコードは、暗号化された patientRecord.ssnフィールドに対して等価クエリを実行します。

3

最後に、mongoose-qe-appディレクトリから次のコマンドを実行中と、前の手順で定義された暗号化操作を実行できます。

npm start

成功した場合、コマンド出力は次の例のようになります。

Successfully inserted the patient document.
Document ID: new ObjectId('...')
Found patient:
{
patientRecord: {
billing: { type: 'Visa', number: '4111111111111111' },
ssn: '987-65-4320',
billAmount: 1500
},
_id: new ObjectId('...'),
patientName: 'Jon Doe',
patientId: 12345678,
__v: 0,
__safeContent__: [
Binary.createFromBase64('EGzhQwBpf1B6W9udskSxJ8kwEEnF5P+SJPZ6ygQ9Ft8=', 0)
]
}
Connection closed.

Mongoose Queryable Encryption のチュートリアルが完了しました。これで、 Queryable Encryptionを使用してドキュメントフィールドを自動的に暗号化および復号化するサンプルMongooseアプリケーションができました。アプリケーションはサーバー側で機密データを暗号化し、クライアント側でデータをクエリします。

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

  • MongoDB Serverマニュアルで、ドライバーQueryable Encryption のチュートリアルをさらに見る

  • Mongooseを使い始める チュートリアルで、 Queryable EncryptionなしでMongooseを使用するアプリケーションを作成する方法を学びます。

  • Mongooseの詳細については、 Mongooseドキュメント を参照してください。

戻る

Mongooseを使い始める

項目一覧