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

Queryable Encryption com Symfony e Doctrine ODM

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.

Antes de iniciar este tutorial, conclua as seguintes tarefas de pré-requisito:

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.

Siga as etapas desta seção para instalar as dependências do projeto , configurar seu ambiente e criar a estrutura do aplicativo .

1

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

2

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.

3

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.php

  • src/Document/PatientRecord.php

  • src/Document/Billing.php

  • src/Command/QueryableEncryptionCommand.php

As etapas futuras deste tutorial instruem você a adicionar código a cada arquivo.

4

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 :

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;
}

Em seguida, cole o seguinte código no arquivo 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;
}

Por fim, cole o seguinte código no arquivo 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;
}

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 igualdade

  • patientRecord.billing: criptografado, mas não consultável

5

Cole o código abaixo no arquivo 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;
}
}

As etapas futuras deste tutorial instruem você a adicionar código em cada comentário correspondente.

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.

1

Em seu arquivo src/Command/QueryableEncryptionCommand.php, adicione o seguinte código abaixo do comentário // Paste application variables below:

src/Command/QueryableEncryptionCommand.php
// 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 __keyVault no banco de dados encryption.

  • 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.

2

Adicione o seguinte código abaixo do comentário // 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,
),
];

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.

3

Adicione o seguinte código diretamente na configuração do provedor KMS da etapa anterior:

src/Command/QueryableEncryptionCommand.php
$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.

4

Adicione o seguinte código abaixo do comentário // 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);

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.

5

Adicione o seguinte código abaixo do comentário // Paste collection setup below:

src/Command/QueryableEncryptionCommand.php
// 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.

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.

1

Em seu arquivo src/Command/QueryableEncryptionCommand.php, adicione o seguinte código abaixo do comentário // 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.'
);

A Queryable Encryption criptografa automaticamente os campos patientRecord.ssn e patientRecord.billing antes de armazenar o documento no MongoDB.

2

Adicione o seguinte código abaixo do comentário // 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.');

Este código executa uma query de igualdade no campo patientRecord.ssn criptografado.

3

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": {
...
}
}
]
}

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:

Voltar

TLS

Nesta página