Join us at MongoDB.local London on 7 May to unlock new possibilities for your data. Use WEB50 to save 50%.
Register now >
Docs Menu
Docs Home
/ /

Symfony と Dotene ODM によるQueryable Encryption

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

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

Tip

Symfony と Dotene をMongoDB PHPライブラリと統合する方法の詳細については、Symfloy MongoDB統合に関するチュートリアルをご覧ください。

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

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

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

1

ターミナルで次のコマンドを実行して、新しい Symfloyアプリケーションを作成し、必要な依存関係をインストールします。

symfony new qe-symfony-app
cd qe-symfony-app
composer require doctrine/mongodb-odm-bundle mongodb/mongodb

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

  • Dotene MongoDB ODM Bundle、Doctene MongoDB ODM の Symfloy 統合

  • PHP用の公式MongoDBドライバーであるMongoDB PHPライブラリ

2

プロジェクトディレクトリで、.envファイルを開き、次の変数を追加または変更します。

MONGODB_URI=<connection URI>
CRYPT_SHARED_LIB_PATH=<Automatic Encryption Shared Library path>

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

3

プロジェクトの src/ディレクトリには、ドキュメント構造とアプリケーションロジックを定義するために次のサブディレクトリとファイルを作成します。

  • src/Document/Patient.php

  • src/Document/PatientRecord.php

  • src/Document/Billing.php

  • src/Command/QueryableEncryptionCommand.php

このチュートリアルの今後の手順では、各ファイルにコードを追加するように指示します。

4

このチュートリアルでは、PatientPatientRecordBilling クラスを使用して人の医療レコードを表します。

次のコードをsrc/Document/Patient.phpファイルに貼り付けます。

src/ドキュメント/Patient.sphere
<?php
namespace App\Document;
use Doctrine\ODM\MongoDB\Mapping\Attribute as ODM;
#[ODM\Document(collection: 'patients')]
class Patient
{
#[ODM\Id]
public string $id;
#[ODM\Field]
public string $patientName;
#[ODM\Field]
public int $patientId;
#[ODM\EmbedOne(targetDocument: PatientRecord::class)]
public PatientRecord $patientRecord;
}

次に、次のコードを src/Document/PatientRecord.phpファイルに貼り付けます。

src/ドキュメント/PatientRecord.html
<?php
namespace App\Document;
use Doctrine\ODM\MongoDB\Mapping\Attribute as ODM;
use Doctrine\ODM\MongoDB\Mapping\EncryptQuery;
#[ODM\EmbeddedDocument]
class PatientRecord
{
#[ODM\Field]
#[ODM\Encrypt(queryType: EncryptQuery::Equality)]
public string $ssn;
#[ODM\EmbedOne(targetDocument: Billing::class)]
#[ODM\Encrypt]
public Billing $billing;
#[ODM\Field]
public int $billAmount;
}

最後に、次のコードを src/Document/Billing.phpファイルに貼り付けます。

src/ドキュメント/ Billing.予定
<?php
namespace App\Document;
use Doctrine\ODM\MongoDB\Mapping\Attribute as ODM;
#[ODM\EmbeddedDocument]
class Billing
{
#[ODM\Field]
public string $type;
#[ODM\Field]
public string $number;
}

ドキュメントクラスは、 patientsコレクション内のドキュメントの構造を定義します。PatientRecordクラスには、次の暗号化されたフィールドを指定するための #[ODM\Encrypt] 属性が含まれています。

  • patientRecord.ssn: 暗号化され、等価クエリ用に構成

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

5

次のコードをsrc/Command/QueryableEncryptionCommand.phpファイルに貼り付けます。

<?php
namespace App\Command;
use App\Document\Billing;
use App\Document\Patient;
use App\Document\PatientRecord;
use Doctrine\ODM\MongoDB\Configuration;
use Doctrine\ODM\MongoDB\DocumentManager;
use Doctrine\ODM\MongoDB\Mapping\Driver\AttributeDriver;
use MongoDB\BSON\Binary;
use MongoDB\Client;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
#[AsCommand(
name: 'app:queryable-encryption',
description: 'Demonstrates Queryable Encryption with '
. 'Doctrine MongoDB ODM',
)]
class QueryableEncryptionCommand extends Command
{
protected function execute(
InputInterface $input,
OutputInterface $output,
): int {
// Paste application variables below
// Paste encryption credentials below
// Paste connection and configuration below
// Paste collection setup below
// Paste insert operation below
// Paste encrypted query below
return Command::SUCCESS;
}
}

このチュートリアルの今後の手順では、対応するコメントごとにコードを追加するように指示します。

プロジェクトファイルと依存関係を設定したら、このセクションの手順に従って暗号化認証情報を構成し、 MongoDBに接続します。

1

src/Command/QueryableEncryptionCommand.phpファイルで、// Paste application variables below コメントの下に次のコードを追加します。

src/Command/QueryableEncryptionCommand.sphere
// Paste application variables below
$keyVaultNamespace = 'encryption.__keyVault';
$encryptedDatabase = 'medicalRecords';
$encryptedCollection = 'patients';

このコードでは、次の変数を設定します。

  • keyVaultNamespace - データ暗号化キー(DEK)を保存するMongoDBの名前空間。このチュートリアルでは、 encryptionデータベース内の __keyVaultコレクションを使用します。

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

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

2

// Paste encryption credentials below コメントの下に次のコードを追加します。

src/Command/QueryableEncryptionCommand.sphere
// Paste encryption credentials below
$keyFile = __DIR__ . '/../../master-key.bin';
if (!file_exists($keyFile)) {
file_put_contents($keyFile, random_bytes(96));
}
$masterKeyBytes = file_get_contents($keyFile);
$kmsProvider = [
'type' => 'local',
'key' => new Binary(
$masterKeyBytes,
Binary::TYPE_GENERIC,
),
];

このコードは、96 バイトのローカル CMKファイルを作成またはロードします。$kmsProvider 配列は、暗号化に使用されるローカル KMS プロバイダーを構成します。

警告

ローカル CMK ストレージ

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

Tip

キーマネジメントシステム

KMS について詳しくは、キー マネジメント のエントリを参照してください。

3

前の手順の KMS プロバイダー構成の直下に次のコードを追加します。

src/Command/QueryableEncryptionCommand.sphere
$autoEncryptionOptions = [
'keyVaultNamespace' => $keyVaultNamespace,
];
$cryptSharedLibPath = $_ENV['CRYPT_SHARED_LIB_PATH'] ?? '';
if ($cryptSharedLibPath) {
$autoEncryptionOptions['extraOptions'] = [
'cryptSharedLibPath' => $cryptSharedLibPath,
];
}

このコードでは、キーヴォールトの名前空間を設定し、自動暗号化共有ライブラリへのパスを構成します。

4

// Paste connection and configuration below コメントの下に次のコードを追加します。

src/Command/QueryableEncryptionCommand.sphere
// Paste connection and configuration below
$cacheDir = __DIR__ . '/../../var/cache/doctrine';
$config = new Configuration();
$config->setAutoEncryption($autoEncryptionOptions);
$config->setKmsProvider($kmsProvider);
$config->setProxyDir($cacheDir . '/Proxies');
$config->setProxyNamespace('Proxies');
$config->setHydratorDir($cacheDir . '/Hydrators');
$config->setHydratorNamespace('Hydrators');
$config->setDefaultDB($encryptedDatabase);
$config->setMetadataDriverImpl(
new AttributeDriver([__DIR__ . '/../Document'])
);
$client = new Client(
uri: $_ENV['MONGODB_URI'],
uriOptions: [],
driverOptions: $config->getDriverOptions(),
);
$dm = DocumentManager::create($client, $config);

このコードは、暗号化設定を使用して Doctrine Configuration オブジェクトを構成し、暗号化ドライバー オプションを渡す MongoDB クライアントを作成し、暗号化操作用の DocumentManager を初期化します。

5

// Paste collection setup below コメントの下に次のコードを追加します。

src/Command/QueryableEncryptionCommand.sphere
// Paste collection setup below
$schemaManager = $dm->getSchemaManager();
$schemaManager->dropDocumentCollection(Patient::class);
$schemaManager->createDocumentCollection(Patient::class);

このコードは、既存のコレクションをすべて削除し、 Queryable Encryptionに必要な暗号化メタデータを持つ新しい patientsコレクションを作成します。createDocumentCollection() を呼び出すたびに、暗号化されたフィールド用に新しいデータ暗号化キーが生成されます。

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

1

src/Command/QueryableEncryptionCommand.phpファイルで、// Paste insert operation below コメントの下に次のコードを追加します。

src/Command/QueryableEncryptionCommand.sphere
// Paste insert operation below
$billing = new Billing();
$billing->type = 'Visa';
$billing->number = '4111111111111111';
$record = new PatientRecord();
$record->ssn = '987-65-4320';
$record->billing = $billing;
$record->billAmount = 1500;
$patient = new Patient();
$patient->patientName = 'Jon Doe';
$patient->patientId = 12345678;
$patient->patientRecord = $record;
$dm->persist($patient);
$dm->flush();
$dm->clear();
$output->writeln(
'Successfully inserted the patient document.'
);

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

2

// Paste encrypted query below コメントの下に次のコードを追加します。

src/Command/QueryableEncryptionCommand.sphere
// Paste encrypted query below
$found = $dm
->getRepository(Patient::class)
->findOneBy(['patientRecord.ssn' => '987-65-4320']);
if ($found instanceof Patient) {
$output->writeln('Found patient:');
$output->writeln(
' Name: ' . $found->patientName
);
$output->writeln(
' SSN: ' . $found->patientRecord->ssn
);
$output->writeln(
' Billing type: '
. $found->patientRecord->billing->type
);
$output->writeln(
' Billing number: '
. $found->patientRecord->billing->number
);
$output->writeln(
' Bill amount: '
. $found->patientRecord->billAmount
);
}
$output->writeln('Connection closed.');

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

3

アプリケーションを起動するには、qe-symfony-appプロジェクトディレクトリから次のコマンドを実行します。

php bin/console app:queryable-encryption

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

Successfully inserted the patient document.
Found patient:
Name: Jon Doe
SSN: 987-65-4320
Billing type: Visa
Billing number: 4111111111111111
Bill amount: 1500
Connection closed.

データベースでは、ドキュメントは暗号化されています。MongoDB は、#[ODM\Encrypt] 属性でマークされたフィールドをBSONバイナリ データとして保存し、メタデータタグの __safeContent__フィールドを含めます。保存されたドキュメントは、次のようになります。

{
"_id": {
"$oid": "..."
},
"patientName": "Jon Doe",
"patientId": 12345678,
"patientRecord": {
"ssn": {
"$binary": {
...
}
},
"billing": {
"$binary": {
...
}
},
"billAmount": 1500
},
"__safeContent__": [
{
"$binary": {
...
}
}
]
}

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

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

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

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

  • Doctrine MongoDB ODM を Symfony と統合する方法の詳細については、Symfony MongoDB 統合チュートリアルを参照してください。

戻る

TLS

項目一覧