Criptografia de campo e consultabilidade
Nesta página
Visão geral
Saiba mais sobre os seguintes tópicos sobre criptografia consultável:
Considerações ao habilitar queries em um campo criptografado.
Como especificar campos para criptografia.
Como configurar um campo criptografado para que seja consultável.
Tipos de query e quais você pode usar em campos criptografados.
Como otimizar o desempenho da query em campos criptografados.
Considerações ao ativar a query
Ao usar a Criptografia Consultável, você pode escolher se deseja tornar um campo criptografado consultável. Se você não precisar executar operações CRUD que exijam que você consulte um campo criptografado, talvez não seja necessário habilitar a query nesse campo. Você ainda pode recuperar o documento inteiro consultando outros campos que podem ser consultados ou não criptografados.
Quando você torna os campos criptografados consultáveis, o Queryable Encryption cria um índice para cada campo criptografado, o que pode tornar as operações de gravação nesse campo mais demoradas. Quando uma operação de gravação atualiza um campo indexado, MongoDB também atualiza o índice relacionado.
Quando você cria uma coleção criptografada, o MongoDB cria duas coleções de metadados, aumentando os requisitos de espaço de armazenamento.
Especifique campos para criptografia
Com o Queryable Encryption, você especifica quais campos deseja criptografar automaticamente em seu documento MongoDB usando um esquema de criptografia JSON. O esquema de criptografia define quais campos são criptografados e quais queries estão disponíveis para esses campos.
Importante
Você pode especificar qualquer campo de criptografia, exceto o campo _id
.
Para especificar campos para criptografia e query, crie um esquema de criptografia que inclua as seguintes propriedades:
Nome da chave | Tipo | Obrigatório |
---|---|---|
| String | Obrigatório |
| String | Obrigatório |
| Binário | Obrigatório. Especifique um valor chave para cada campo. ObservaçãoSe você chamar |
| Objeto | Opcional. Incluir para tornar o campo consultável. |
Exemplo
Este exemplo mostra como criar o esquema de criptografia.
Considere o seguinte documento que contenha informações de identificação pessoal (PII), informações de cartão de crédito e informações médicas confidenciais:
{ "firstName": "Jon", "lastName": "Snow", "patientId": 12345187, "address": "123 Cherry Ave", "medications": [ "Adderall", "Lipitor" ], "patientInfo": { "ssn": "921-12-1234", "billing": { "type": "visa", "number": "1234-1234-1234-1234" } } }
Para garantir que os PII e as informações médicas confidenciais permaneçam seguras, crie o esquema de criptografia e configure esses campos para criptografia automática. Você deve gerar uma chave exclusiva para cada campo criptografado com antecedência. Por exemplo:
const encryptedFieldsObject = { fields: [ { path: "patientId", keyId: "<unique data encryption key>", bsonType: "int" }, { path: "patientInfo.ssn", keyId: "<unique data encryption key>", bsonType: "string" }, { path: "medications", keyId: "<unique data encryption key>", bsonType: "array" }, { path: "patientInfo.billing", keyId: "<unique data encryption key>", bsonType: "object" } ] }
Configure AutoEncryptionSettings
no cliente e, em seguida, use o método assistente createEncryptedCollection()
para criar suas coleções.
Configurar campos para queries
Inclua a propriedade queries
em campos para torná-los consultáveis. Isso permite que um cliente autorizado emita queries de leitura e escrita nesses campos. A omissão da propriedade queries
impede que os clientes consultem um campo.
Exemplo
Adicione a propriedade queries
ao exemplo de esquema anterior para tornar os campos patientId
e patientInfo.ssn
aptos para queries.
const encryptedFieldsObject = { fields: [ { path: "patientId", bsonType: "int", queries: { queryType: "equality" } }, { path: "patientInfo.ssn", bsonType: "string", queries: { queryType: "equality" } }, { path: "medications", bsonType: "array" }, { path: "patientInfo.billing", bsonType: "object" }, ] }
Contenção
Operações de gravação simultâneas, como inserir o mesmo par de campo/valor em vários documentos em sucessão próxima, podem causar contenção: conflitos que atrasam as operações.
Com o Queryable Encryption, o MongoDB rastreia as ocorrências de cada par de campo/valor em uma coleção criptografada usando um contador interno. O fator de contenção particiona esse contador, semelhante a uma array. Isto minimiza problemas ao incrementar o contador ao utilizar insert
, update
ou findAndModify
para adicionar ou modificar um campo codificado com o mesmo par de campo/valor em sucessão próxima. contention = 0
cria uma array com um elemento no índice 0. contention = 4
cria uma array com elementos 5 nos índices 0-4. O MongoDB incrementa um elemento de array aleatório durante a inserção.
Ao não ser definido, o contention
padroniza para 8
, que fornece alto desempenho para a maioria das cargas de trabalho. Uma contenção mais alta melhora o desempenho das operações de inserção e atualização em campos de baixa cardinalidade , no entanto, reduz o desempenho da procuras.
Ajustando o fator de contenção
Opcionalmente, você pode incluir a propriedade contention
em campos consultáveis para alterar o fator de contenção de seu valor padrão de 8
. Antes de modificar o fator de contenção, considere os seguintes pontos:
Considere aumentar contention
acima do valor padrão de 8
somente se o campo tiver operações de gravação simultâneas frequentes. Como os altos valores de contenção sacrificam o desempenho de busca em favor das operações de inserção e atualização, é improvável que o benefício de um alto fator de contenção para um campo raramente atualizado supere a desvantagem.
Considere diminuir contention
se um campo é frequentemente consultado, mas raramente escrito. Nesse caso, encontrar desempenho é preferível a gravar e atualizar o desempenho.
Você pode calcular o fator de contenção de um campo usando uma fórmula em que:
ω
é o número de operações de gravação simultâneas no campo em um curto período de tempo, como 30ms. Se desconhecido, você pode usar o número de núcleos virtuais do servidor.valinserts
é o número de pares de campo/valor únicos inseridos desde a última compactação de metadados.ω
} éω/valinserts
arredondado para o número inteiro mais próximo. Para um volume de trabalho de 100 operações com 1000 valores recentes,100/1000 = 0.1
, que arredonda para1
.
Um fator de contenção razoável, cf
, é o resultado da seguinte fórmula, arredondada para o número inteiro positivo mais próximo:
(ω
∗ · (ω
∗ − 1)) / 0.2
Por exemplo, se houver 100 operações de gravação simultâneas em um campo em 30 ms, então ω = 100
. Se houver 50 valores exclusivos recentes para esse campo, então ω
∗ = 100/50 = 2
. Isso resulta em cf = (2·1)/0.2 = 10
.
Aviso
Não defina o fator de contenção nas propriedades dos próprios dados, como a frequência dos pares de campo/valor (cardinalidade). Defina o fator de contenção apenas com base no seu volume de trabalho.
Considere um caso em que ω = 100
e valinserts = 1000
, resultando em ω
∗ =
100/1000 = 0.1 ≈ 1
e cf = (1·0)/0.2 = 0 ≈ 1
. 20 dos valores aparecem com muita frequência, então você define contention = 3
em vez disso. Um invasor com acesso a vários instantâneos do banco de dados de dados pode inferir que a configuração alta indica pares de campo/valor frequentes. Nesse caso, deixar contention
sem definir para que o padrão seja 8
impediria que o invasor tivesse essas informações.
Para obter informações completas sobre a contenção e suas implicações criptográficas, consulte "Seção 9: Diretivas" noDocumento técnico sobre Queryable Encryption do MongoDB
Tipos de query
Passar um tipo de query para a opção queries
em seu objeto de campos criptografados define os tipos de query permitidos para o campo. A query de campos não criptografados ou campos criptografados com um tipo de query com suporte retorna dados criptografados que são descriptografados no cliente.
Atualmente, a Queryable Encryption oferece suporte aos tipos de query none
e equality
. Se o tipo de query não for especificado, o padrão será none
. Se o tipo de query for none
, o campo será codificado, mas os clientes não poderão consultá-lo.
O tipo de query do equality
suporta as seguintes expressões:
Observação
As queries que comparam um campo codificado com null
ou com uma expressão regular resultam em um erro, mesmo com operadores de query suportados.
As Queryable Encryption equality
não suportam operações de leitura ou gravação em um campo quando a operação compara o campo criptografado a qualquer um dos seguintes tipos BSON:
double
decimal128
object
array
Esquemas de cliente e servidor
O MongoDB suporta o uso da validação de esquema para impor a criptografia de campos específicos em uma coleção. Clientes que usam criptografia automática consultável têm um comportamento específico dependendo da configuração da conexão com o banco de dados:
Se o objeto de conexão
encryptedFieldsMap
contiver uma chave para a coleção especificada, o cliente utilizará esse objeto para executar a Queryable Encryption automática, ao invés de utilizar o esquema remoto. No mínimo, as regras locais devem criptografar os campos que o esquema remoto marca como exigindo criptografia.Se o objeto de conexão
encryptedFieldsMap
não contiver uma chave para a coleção especificada, o cliente baixará o esquema remoto do lado do servidor para a coleção e o usará para executar a Queryable Encryption automática.Importante
Considerações de comportamento
Quando um cliente não tem um esquema de criptografia para a coleção especificada, ocorre o seguinte:
O cliente confia que o servidor tem um esquema válido com relação à criptografia automática consultável.
O cliente usa o esquema remoto apenas para executar uma Queryable Encryption automática. O cliente não força nenhuma outra regra de validação especificada no esquema.
Para saber mais sobre o Queryable Encryption automático, consulte os seguintes recursos:
Habilitar queryable encryption
Queryable Encryption antes de criar uma coleção. A ativação da criptografia consultável após a criação de uma coleção não criptografa campos em documentos que já estão nessa coleção. Você pode ativar a Queryable Encryption em campos de duas maneiras:
Passe o esquema de criptografia, representado pela constante do
encryptedFieldsObject
, para o cliente que o aplicativo usa para criar a coleção:
const client = new MongoClient(uri, { autoEncryption: { keyVaultNameSpace: "<your keyvault namespace>", kmsProviders: "<your kms provider>", extraOptions: { cryptSharedLibPath: "<path to Automatic Encryption Shared Library>" }, encryptedFieldsMap: { "<databaseName.collectionName>": { encryptedFieldsObject } } } ... await client.db("<database name>").createCollection("<collection name>"); }
Para obter mais informações sobre as opções de configuração autoEncryption
, consulte a seção sobre MongoClient Options for Queryable Encryption.
Passe o objeto de campos criptografados para
createCollection()
para criar uma nova coleção
await encryptedDB.createCollection("<collection name>", { encryptedFields: encryptedFieldsObject });
Dica
Especifique os campos criptografados ao criar a coleção e também ao criar um cliente para acessar a coleção. Isso garante que, se a segurança do servidor for comprometida, as informações ainda serão criptografadas por meio do cliente.
Importante
Crie sua coleção explicitamente, ao invés de criá-la implicitamente com uma operação de inserção. Quando você cria uma coleção utilizando createCollection()
, MongoDB cria um índice nos campos codificados. Sem esse índice, queries em campos criptografados podem ser executadas lentamente.