개요
이 가이드 에서는 Doctrine MongoDB ODM 을 사용하여 MongoDB의 Queryable Encryption 기능 구현 하는 Symfony 애플리케이션 만드는 방법을 학습 수 있습니다.
Queryable Encryption 사용하면 문서 필드를 자동으로 암호화하고 해독할 수 있습니다. Queryable Encryption 사용하여 애플리케이션 의 민감한 데이터를 암호화하고, 데이터 필드를 서버 에 무작위로 암호화됨 데이터로 저장 , 암호화됨 필드를 쿼리 수 있습니다. 이 튜토리얼에서는 PHP 애플리케이션용 ODM(객체 문서 매퍼)을 제공하는 Doctrine MongoDB ODM을 사용하여 Queryable Encryption 설정하다 방법을 보여줍니다.
팁
Symfony 및 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-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 드라이버
환경 변수를 지정합니다.
프로젝트 디렉토리 에서 .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 파일 에 붙여넣습니다.
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 파일 에 붙여넣습니다.
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 파일 에 붙여넣습니다.
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; ( 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 주석 아래에 다음 코드를 추가합니다.
// Paste application variables below $keyVaultNamespace = 'encryption.__keyVault'; $encryptedDatabase = 'medicalRecords'; $encryptedCollection = 'patients';
이 코드는 다음 변수를 설정합니다.
keyVaultNamespace - DEK(데이터 암호화 키)를 저장하는 MongoDB 의 네임스페이스 . 이 튜토리얼에서는
encryption데이터베이스 의__keyVault컬렉션 사용합니다.encryptionDatabase - 암호화됨 데이터를 저장하는 데이터베이스 입니다. 이 튜토리얼에서는
medicalRecords데이터베이스 사용합니다.encryptionCollection - 암호화됨 데이터를 저장하는 컬렉션 입니다. 이 튜토리얼에서는
patients컬렉션 사용합니다.
고객 마스터 키 구성합니다.
// Paste encryption credentials below 주석 아래에 다음 코드를 추가합니다.
// 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 제공자 구성 바로 아래에 다음 코드를 추가합니다.
$autoEncryptionOptions = [ 'keyVaultNamespace' => $keyVaultNamespace, ]; $cryptSharedLibPath = $_ENV['CRYPT_SHARED_LIB_PATH'] ?? ''; if ($cryptSharedLibPath) { $autoEncryptionOptions['extraOptions'] = [ 'cryptSharedLibPath' => $cryptSharedLibPath, ]; }
이 코드는 키 볼트 네임스페이스 설정하고 자동 암호화 공유 라이브러리의 경로를 구성합니다.
을(를) DocumentManager 구성합니다.
// Paste connection and configuration below 주석 아래에 다음 코드를 추가합니다.
// 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 주석 아래에 다음 코드를 추가합니다.
// 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 주석 아래에 다음 코드를 추가합니다.
// 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 주석 아래에 다음 코드를 추가합니다.
// 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: 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에 대해 자세히 학습 다음 리소스를 방문하세요.
MongoDB Server 매뉴얼에서 더 많은 드라이버 Queryable Encryption 튜토리얼을 확인하세요.
Doctrine MongoDB ODM 문서에서 Doctrine MongoDB ODM 에 대해 자세히 보기 .
Symfony MongoDB 통합 튜토리얼에서 Doctrine MongoDB ODM을 Symfony와 통합하는 방법에 대해 자세히 보기 .