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 및 Doctrine ODM을 사용한 Queryable Encryption

이 가이드 에서는 Doctrine MongoDB ODM 을 사용하여 MongoDB의 Queryable Encryption 기능 구현 하는 Symfony 애플리케이션 만드는 방법을 학습 수 있습니다.

Queryable Encryption 사용하면 문서 필드를 자동으로 암호화하고 해독할 수 있습니다. Queryable Encryption 사용하여 애플리케이션 의 민감한 데이터를 암호화하고, 데이터 필드를 서버 에 무작위로 암호화됨 데이터로 저장 , 암호화됨 필드를 쿼리 수 있습니다. 이 튜토리얼에서는 PHP 애플리케이션용 ODM(객체 문서 매퍼)을 제공하는 Doctrine MongoDB ODM을 사용하여 Queryable Encryption 설정하다 방법을 보여줍니다.

Symfony 및 Doctrine을 MongoDB PHP 라이브러리와 통합하는 방법에 대해 자세히 학습하려면 Symfony MongoDB 통합 튜토리얼 을 참조하세요.

이 튜토리얼을 시작하기 전에 다음 전제 조건 작업을 완료하세요.

이 튜토리얼에서는 Symfony 및 Doctrine MongoDB ODM을 사용하는 Queryable Encryption 애플리케이션 만드는 방법을 보여줍니다. 이 애플리케이션 환자의 의료 기록을 암호화 및 복호화하고 암호화됨 의료 데이터를 쿼리합니다.

이 섹션의 단계에 따라 프로젝트 종속성을 설치하고, 환경을 구성하고, 애플리케이션 구조를 만듭니다.

1

터미널에서 다음 명령을 실행하여 새 Symfony 애플리케이션 만들고 필요한 종속 항목을 설치합니다.

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

이 명령은 qe-symfony-app 프로젝트 디렉토리 만들고 다음 종속성을 설치합니다.

  • Doctrine MongoDB ODM Bundle, Doctrine MongoDB ODM을 위한 Symfony 통합

  • MongoDB PHP 라이브러리, PHP 용 공식 MongoDB 드라이버

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

이 튜토리얼에서는 Patient, PatientRecordBilling 클래스를 사용하여 환자 의료 기록을 나타냅니다.

다음 코드를 src/Document/Patient.php 파일 에 붙여넣습니다.

src/Document/Patient.php
<?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/Document/PatientRecord.php
<?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/Document/Billing.php
<?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.php
// Paste application variables below
$keyVaultNamespace = 'encryption.__keyVault';
$encryptedDatabase = 'medicalRecords';
$encryptedCollection = 'patients';

이 코드는 다음 변수를 설정합니다.

  • keyVaultNamespace - DEK(데이터 암호화 키)를 저장하는 MongoDB 의 네임스페이스 . 이 튜토리얼에서는 encryption 데이터베이스 의 __keyVault 컬렉션 사용합니다.

  • encryptionDatabase - 암호화됨 데이터를 저장하는 데이터베이스 입니다. 이 튜토리얼에서는 medicalRecords 데이터베이스 사용합니다.

  • encryptionCollection - 암호화됨 데이터를 저장하는 컬렉션 입니다. 이 튜토리얼에서는 patients 컬렉션 사용합니다.

2

// Paste encryption credentials below 주석 아래에 다음 코드를 추가합니다.

src/Command/QueryableEncryptionCommand.php
// 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바이트 로컬 고객 마스터 키 파일 생성하거나 로드합니다. $kmsProvider 배열 암호화 에 사용되는 로컬 KMS 제공자 구성합니다.

경고

로컬 고객 마스터 키 저장

이 튜토리얼에서는 고객 마스터 키 로컬 파일 에 저장합니다. 프로덕션 환경에서는 이 접근 방식을 사용하지 마세요. 원격 KMS 없으면 암호화 키 에 무단으로 액세스 하거나 데이터를 해독하는 데 필요한 키를 잃을 위험이 있습니다.

키 관리 시스템

KMS 에 대해 자세히 학습하려면 키 관리 Wikipedia 항목을 참조하세요.

3

이전 단계의 KMS 제공자 구성 바로 아래에 다음 코드를 추가합니다.

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

이 코드는 키 볼트 네임스페이스 설정하고 자동 암호화 공유 라이브러리의 경로를 구성합니다.

4

// Paste connection and configuration below 주석 아래에 다음 코드를 추가합니다.

src/Command/QueryableEncryptionCommand.php
// 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.php
// 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.php
// 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.ssnpatientRecord.billing 필드를 자동으로 암호화합니다.

2

// Paste encrypted query below 주석 아래에 다음 코드를 추가합니다.

src/Command/QueryableEncryptionCommand.php
// 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": {
...
}
}
]
}

Doctrine ODM Queryable Encryption 튜토리얼을 완료한 것을 축하합니다! 이제 Queryable Encryption 사용하여 문서 필드를 자동으로 암호화하고 해독하는 샘플 Symfony 애플리케이션 생겼습니다. 애플리케이션 은 서버 사이드에서 민감한 데이터를 암호화하고 클라이언트 사이드에서 데이터를 쿼리합니다.

Queryable Encryption 및 Doctrine MongoDB ODM에 대해 자세히 학습 다음 리소스를 방문하세요.

돌아가기

TLS

이 페이지의 내용