개요
이 가이드 에서는 Doctrine MongoDB ODM 을 사용하여 MongoDB의 Queryable Encryption 기능 구현 하는 Symfony 애플리케이션 만드는 방법을 학습 수 있습니다.
Queryable Encryption 사용하면 문서 필드를 자동으로 암호화하고 해독할 수 있습니다. Queryable Encryption 사용하여 애플리케이션 의 민감한 데이터를 암호화하고, 데이터 필드를 서버 에 무작위로 암호화됨 데이터로 저장 , 암호화됨 필드를 쿼리 수 있습니다. 이 튜토리얼에서는 PHP 애플리케이션용 ODM(객체 문서 매퍼)을 제공하는 Doctrine MongoDB ODM을 사용하여 Queryable Encryption 설정하다 방법을 보여줍니다.
팁
Symfony and Doctrine을 MongoDB PHP 라이브러리와 통합하는 방법에 대해 자세히 학습 Symfony MongoDB 통합 튜토리얼 을 참조하세요.
전제 조건
이 튜토리얼을 시작하기 전에 다음 전제 조건 작업을 완료하세요.
MongoDB Atlas 계정을 만들고 클러스터 구성합니다. 클러스터 가 MongoDB Server 버전 7.0 이상에서 실행되는지 확인합니다. 자세한 학습 은 MongoDB 시작하기 가이드 참조하세요.
자동 암호화 공유 라이브러리를 다운로드합니다. 지침을 보려면 쿼리 분석 구성 요소 설치 및 구성 가이드 참조하세요.
PHP 확장을 다운로드합니다. 자세한 학습 은 확장 문서에서 설치 를 참조하세요.
PHP 8.1 이상을 설치합니다.
Composer 2.0 이상을 설치합니다.
Symfony CLI 설치합니다. 자세한 학습 은 Symfony CLI 설명서를 참조하세요.
튜토리얼
이 튜토리얼에서는 Symfony 및 Doctrine MongoDB ODM을 사용하는 Queryable Encryption 애플리케이션 만드는 방법을 보여줍니다. 이 애플리케이션 환자의 의료 기록을 암호화 및 복호화하고 암호화됨 의료 데이터를 쿼리합니다.
프로젝트 설정
이 섹션의 단계에 따라 프로젝트 종속성을 설치하고, 환경을 구성하고, 애플리케이션 구조를 만듭니다.
환경을 설정합니다.
터미널에서 다음 명령을 실행하여 새 Symfony 애플리케이션 만들고 필요한 종속 항목을 설치합니다.
symfony new qe-symfony-appcd qe-symfony-appcomposer require doctrine/mongodb-odm-bundle mongodb/mongodb이 명령은 qe-symfony-app 프로젝트 디렉토리 만들고 다음 종속성을 설치합니다.
Doctrine MongoDB ODM Bundle, Doctrine MongoDB ODM을 위한 Symfony 통합
MongoDB PHP 라이브러리, PHP 용 공식 MongoDB 드라이버
환경 변수를 지정합니다.
프로젝트 디렉토리 에서 .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 를 가리키는지 확인합니다.
문서 클래스를 정의합니다.
이 튜토리얼에서는 Patient, PatientRecord 및 Billing 클래스를 사용하여 환자 의료 기록을 나타냅니다.
다음 코드를 src/Document/Patient.php 파일 에 붙여넣습니다.
src/Document/Patient.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
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
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: 암호화되었지만 쿼리할 수 없음
콘솔 명령을 만듭니다.
다음 코드를 src/Command/QueryableEncryptionCommand.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 암호화 및 연결
프로젝트 파일 및 종속성을 설정한 후 이 섹션의 단계에 따라 암호화 자격 증명 구성하고 MongoDB 에 연결합니다.
애플리케이션 변수를 할당합니다.
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컬렉션 사용합니다.
고객 마스터 키 구성합니다.
// Paste encryption credentials below 주석 아래에 다음 코드를 추가합니다.
src/Command/QueryableEncryptionCommand.php
// Paste encryption credentials below// Warning: Local key files are for development only. Use a remote KMS in production.$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 제공자 구성 바로 아래에 다음 코드를 추가합니다.
src/Command/QueryableEncryptionCommand.php
$autoEncryptionOptions = [ 'keyVaultNamespace' => $keyVaultNamespace,];
$cryptSharedLibPath = $_ENV['CRYPT_SHARED_LIB_PATH'] ?? '';if ($cryptSharedLibPath) { $autoEncryptionOptions['extraOptions'] = [ 'cryptSharedLibPath' => $cryptSharedLibPath, ];}이 코드는 키 볼트 네임스페이스 설정하고 자동 암호화 공유 라이브러리의 경로를 구성합니다.
을(를) DocumentManager 구성합니다.
// 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 를 초기화합니다.
암호화됨 컬렉션 만듭니다.
// 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() 을(를) 호출할 때마다 암호화됨 필드에 대한 새 데이터 암호화 키가 생성됩니다.
암호화된 작업 수행
애플리케이션 과 데이터베이스 연결을 구성한 후 이 섹션의 단계에 따라 암호화됨 문서를 삽입하고 쿼리 .
암호화됨 데이터를 삽입합니다.
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.ssn 및 patientRecord.billing 필드를 자동으로 암호화합니다.
암호화됨 데이터를 쿼리합니다.
// 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 필드 에 대해 동등성 쿼리 수행합니다.
애플리케이션 실행합니다.
애플리케이션 시작하려면 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: 1500Connection 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에 대해 자세히 학습 다음 리소스를 방문하세요.
MongoDB Server 매뉴얼에서 더 많은 드라이버 Queryable Encryption 튜토리얼을 확인하세요.
Doctrine MongoDB ODM 문서에서 Doctrine MongoDB ODM 에 대해 자세히 보기 .
Symfony MongoDB 통합 튜토리얼에서 Doctrine MongoDB ODM을 Symfony와 통합하는 방법에 대해 자세히 보기 .