Visão geral
Neste guia, você pode aprender a criar um aplicativo Symfony que usa Doctrine MongoDB ODM para implementar o recurso de Queryable Encryption do MongoDB.
A Queryable Encryption permite criptografar e descriptografar automaticamente os campos do documento . Você pode usar a Queryable Encryption para criptografar dados confidenciais em seu aplicativo, armazenar campos de dados como dados criptografados aleatórios no servidor e query os campos criptografados. Este tutorial mostra como configurar a Queryable Encryption usando o Doctrine MongoDB ODM, que fornece um Objeto Documento Mapper (ODM) para aplicativos PHP.
Dica
Para **aprender** mais sobre como integrar o Symfony e o Doctrine com a **biblioteca** PHP do MongoDB, consulte o tutorial de integração do Symfony com o MongoDB.
Pré-requisitos
Antes de iniciar este tutorial, conclua as seguintes tarefas de pré-requisito:
Crie uma conta MongoDB Atlas e configure um cluster. Certifique-se de que seu cluster seja executado no MongoDB Server versão 7.0 ou posterior. Para saber mais, consulte o guia Introdução ao MongoDB.
Baixe a biblioteca compartilhada de criptografia automática. Para visualizar as instruções, consulte o guia Instalar e configurar um componente de análise de query.
Baixe a extensão PHP. Para aprender mais, consulte Instalação na documentação da extensão.
Instale o PHP 8.1 ou posterior.
Instale o Composer 2.0 ou posterior.
Instale o Symfony CLI. Para aprender mais, consulte a documentação do Symfony CLI.
Tutorial
Este tutorial mostra como criar um aplicativo Queryable Encryption que usa Symfony e Doctrine MongoDB ODM. O aplicativo criptografa e descriptografa registros médicas de pacientes e consulta dados médicas criptografados.
Configurar seu projeto
Siga as etapas desta seção para instalar as dependências do projeto , configurar seu ambiente e criar a estrutura do aplicativo .
Configure seu ambiente.
Execute os seguintes comandos no seu terminal para criar um novo aplicativo Symfony e instalar as dependências necessárias:
symfony new qe-symfony-app cd qe-symfony-app composer require doctrine/mongodb-odm-bundle mongodb/mongodb
Estes comandos criam um diretório de projeto do qe-symfony-app e instalam as seguintes dependências:
Doctrine MongoDB ODM Bundle, a integração do Symfony para Doctrine MongoDB ODM
Biblioteca PHP do MongoDB , o driver oficial do MongoDB para PHP
Especifique suas variáveis de ambiente.
No diretório do projeto , abra o arquivo .env e adicione ou modifique as seguintes variáveis:
MONGODB_URI=<connection URI> CRYPT_SHARED_LIB_PATH=<Automatic Encryption Shared Library path>
Substitua o espaço reservado <connection URI> pelo URI de conexão que se conecta ao seu cluster e substitua <Automatic Encryption Shared Library path> pelo caminho completo para sua Biblioteca compartilhada de criptografia automática. Certifique-se de que o caminho aponte para lib/mongo_crypt_v1.dylib dentro do pacote baixado.
Crie seus arquivos de aplicativo.
No diretório src/ do seu projeto, crie os seguintes subdiretórios e arquivos para definir a estrutura do documento e a lógica do aplicativo:
src/Document/Patient.phpsrc/Document/PatientRecord.phpsrc/Document/Billing.phpsrc/Command/QueryableEncryptionCommand.php
As etapas futuras deste tutorial instruem você a adicionar código a cada arquivo.
Defina suas classes de documento .
Este tutorial utiliza classes Patient, PatientRecord e Billing para representar registros médicas de pacientes.
Cole o código abaixo no arquivo 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; }
Em seguida, cole o seguinte código no arquivo 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; }
Por fim, cole o seguinte código no arquivo 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; }
As classes de documento definem a estrutura para documentos na coleção patients. A classe PatientRecord inclui o atributo #[ODM\Encrypt] para especificar os seguintes campos criptografados:
patientRecord.ssn: criptografado e configurado para queries de igualdadepatientRecord.billing: criptografado, mas não consultável
Crie seu comando do console.
Cole o código abaixo no arquivo 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; } }
As etapas futuras deste tutorial instruem você a adicionar código em cada comentário correspondente.
Criptografar e conectar ao MongoDB
Após configurar seus arquivos de projeto e dependências, siga as etapas nesta seção para configurar suas credenciais de criptografia e conectar ao MongoDB.
Atribua suas variáveis de aplicativo.
Em seu arquivo src/Command/QueryableEncryptionCommand.php, adicione o seguinte código abaixo do comentário // Paste application variables below:
// Paste application variables below $keyVaultNamespace = 'encryption.__keyVault'; $encryptedDatabase = 'medicalRecords'; $encryptedCollection = 'patients';
O código define as seguintes variáveis:
keyVaultNamespace - O namespace no MongoDB que armazena suas chaves de criptografia de dados (DEKs). Este tutorial utiliza a coleção
__keyVaultno banco de dadosencryption.encryptionDatabase - O banco de dados que armazena seus dados criptografados. Este tutorial utiliza o banco de dados
medicalRecords.encryptedCollection - A coleção que armazena seus dados criptografados. Este tutorial utiliza a coleção
patients.
Configure sua chave mestra do cliente.
Adicione o seguinte código abaixo do comentário // 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, ), ];
Esse código cria ou carrega um arquivo de chave mestra do cliente local de 96bytes. O $kmsProvider array configura o provedor KMS local usado para criptografia.
Aviso
Armazenamento local da chave mestra do cliente
Este tutorial armazena sua chave mestra do cliente em um arquivo local. Não use essa abordagem na produção. Sem um KMS remoto, você corre o risco de acesso não autorizado à chave de criptografia ou de perda da chave necessária para descriptografar seus dados.
Dica
Sistemas de gerenciamento de chaves
Para saber mais sobre o KMS, veja o verbete Key Management na Wikipedia.
Configure suas opções de criptografia automática.
Adicione o seguinte código diretamente na configuração do provedor KMS da etapa anterior:
$autoEncryptionOptions = [ 'keyVaultNamespace' => $keyVaultNamespace, ]; $cryptSharedLibPath = $_ENV['CRYPT_SHARED_LIB_PATH'] ?? ''; if ($cryptSharedLibPath) { $autoEncryptionOptions['extraOptions'] = [ 'cryptSharedLibPath' => $cryptSharedLibPath, ]; }
Esse código define o namespace do cofre de chaves e configura o caminho para a biblioteca compartilhada de criptografia automática.
Configure seu DocumentManager.
Adicione o seguinte código abaixo do comentário // 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);
Esse código configura um objeto Doctrine Configuration com suas configurações de criptografia, cria um cliente MongoDB que passa opções de driver de criptografia e inicializa um DocumentManager para operações criptografadas.
Crie sua coleção criptografada.
Adicione o seguinte código abaixo do comentário // Paste collection setup below:
// Paste collection setup below $schemaManager = $dm->getSchemaManager(); $schemaManager->dropDocumentCollection(Patient::class); $schemaManager->createDocumentCollection(Patient::class);
Esse código descarta qualquer coleção existente e cria uma nova coleção patients com os metadados de criptografia necessários para a Queryable Encryption. Cada chamada para createDocumentCollection() gera novas chaves de criptografia de dados para os campos criptografados.
Realizar operações criptografadas
Depois de configurar o aplicativo e a conexão do banco de dados, siga as etapas nesta seção para inserir e query documentos criptografados.
Insira dados criptografados.
Em seu arquivo src/Command/QueryableEncryptionCommand.php, adicione o seguinte código abaixo do comentário // 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.' );
A Queryable Encryption criptografa automaticamente os campos patientRecord.ssn e patientRecord.billing antes de armazenar o documento no MongoDB.
Consultar query criptografados.
Adicione o seguinte código abaixo do comentário // 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.');
Este código executa uma query de igualdade no campo patientRecord.ssn criptografado.
Execute seu aplicação.
Para iniciar seu aplicativo, execute o seguinte comando a partir do seu diretório de projeto do qe-symfony-app:
php bin/console app:queryable-encryption
Se for bem-sucedida, a saída do comando será semelhante ao exemplo a seguir:
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.
No banco de dados, o documento é criptografado. O MongoDB armazena campos marcados com o atributo #[ODM\Encrypt] como dados binários BSON e inclui um campo __safeContent__ para tags de metadados. O documento armazenado é semelhante ao seguinte:
{ "_id": { "$oid": "..." }, "patientName": "Jon Doe", "patientId": 12345678, "patientRecord": { "ssn": { "$binary": { ... } }, "billing": { "$binary": { ... } }, "billAmount": 1500 }, "__safeContent__": [ { "$binary": { ... } } ] }
Próximos passos
Parabéns por concluir o tutorial Doctrine ODM Queryable Encryption ! Agora você tem um aplicativo Symfony de amostra que usa o Queryable Encryption para criptografar e descriptografar automaticamente os campos do documento. Seu aplicativo criptografa dados confidenciais no lado do servidor e query os dados no lado do cliente.
Para saber mais sobre Queryable Encryption e Doctrine MongoDB ODM, visite os seguintes recursos:
Veja mais tutoriais de Queryable Encryption do driver no manual do MongoDB Server.
Aprenda mais sobre o Doctrine MongoDB ODM na documentação do Doctrine MongoDB ODM.
Saiba mais sobre a integração do Doctrine MongoDB ODM com o Symfony no tutorial Integração do Symfony MongoDB.