Visão geral
Você pode usar o driver Node.js para criptografar campos específicos do documento usando um conjunto de recursos chamado criptografia em uso. A criptografia em uso permite que seu aplicativo criptografe os dados antes de enviá-los para o MongoDB e consulte documentos com campos criptografados.
Aviso
MongoDB 8.2 Problema conhecido
A versão 8.2.0 do mongocryptd pode não ser executada no Windows. Esse bug afeta a criptografia em execução com o driver se você especificar o argumento --logpath NUL ao iniciar mongocryptd.
Para saber mais sobre esse problema e como resolvê-lo, consulte Problemas conhecidos nas Notas de versão do MongoDB..82
A criptografia em uso impede que usuários não autorizados visualizem dados em texto simples à medida que são enviados ao MongoDB ou enquanto estão em um banco de dados criptografado. Para ativar a Criptografia em execução em uma aplicação e autorizá-la a descriptografar dados, você deve criar chaves de encriptação que somente sua aplicação possa acessar. Somente aplicativos que têm acesso às suas chaves de criptografia podem acessar os dados descriptografados em texto simples. Se um invasor obtiver acesso ao banco de dados, ele só poderá ver os dados de texto cifrado criptografados porque não tem acesso às chaves de encriptação.
Você pode usar criptografia em uso para criptografar campos em seus documentos MongoDB que contêm os seguintes tipos de dados confidenciais:
Números de cartão de crédito
Endereços
Informação de saúde
Informações financeiras
Qualquer outra informação sensível ou pessoalmente identificável (PII)
O MongoDB oferece os seguintes recursos para habilitar a criptografia em uso:
Queryable Encryption
Queryable Encryption (QE) é um recurso de criptografia em execução que permite executar query em valores de campo criptografados, incluindo query de igualdade, faixa e prefixo, sufixo e substring. O suporte a query de faixa requer MongoDB Server 8.0 ou posterior. O suporte a query de prefixo, sufixo e substring requer MongoDB Server 9.0 ou posterior.
Para saber mais sobre Queryable Encryption, consulte Queryable Encryption no manual do MongoDB Server .
Criptografia no nível de campo no lado do cliente
A criptografia no nível do campo do lado do cliente (CSFLE) foi introduzida na versão 4.2 do Servidor MongoDB e oferece suporte à busca de igualdade em campos criptografados. O CSFLE difere da Queryable Encryption porque você pode selecionar um algoritmo de criptografia determinístico ou aleatório para criptografar campos. Você só pode consultar campos criptografados que usam um algoritmo de criptografia determinístico ao usar o CSFLE. Quando você usa um algoritmo de criptografia aleatório para criptografar campos no CSFLE, eles podem ser descriptografados, mas não é possível executar query de igualdade nesses campos. Ao usar a Queryable Encryption, você não pode especificar o algoritmo de criptografia, mas pode consultar todos os campos criptografados.
Quando você criptografa deterministicamente um valor, o mesmo valor de entrada produz o mesmo valor de saída. Enquanto a criptografia determinística permite que você execute queries nesses campos criptografados, os dados criptografados com baixa cardinalidade são suscetíveis à quebra de código por análise de frequência.
Dica
Para saber mais sobre esses conceitos, consulte as seguintes entradas na Wikipedia:
Para saber mais sobre CSFLE, consulte CSFLE no manual do servidor.
Suporte a pipeline de agregação
A partir do MongoDB Server 8.1, você pode usar o estágio de agregação $lookup com clientes configurados para criptografia em execução. Esse recurso requer mongodb-client-encryption versão do pacote 6.3.0 ou posterior.
O estágio $lookup permite unir dados relacionados em coleções criptografadas sem precisar buscar e combinar documentos manualmente no código do aplicativo. Tanto a coleção de origem quanto a coleção from devem ser configuradas para criptografia em execução. Os campos especificados em localField e foreignField não podem ser campos criptografados.
O exemplo seguinte mostra uma operação $lookup em uma coleção criptografada:
const pipeline = [ { $lookup: { from: "encryptedCollection", localField: "userId", foreignField: "_id", as: "userDetails" } } ]; const results = await collection.aggregate(pipeline).toArray();
Direcionar solicitações KMS por meio de um proxy HTTP
A partir da versão do driver Node.js 7.6, você pode rotear as solicitações que o driver do Node.js faz ao seu sistema de gerenciamento de chaves (KMS) por meio de um proxy HTTP. Use esse recurso quando seu ambiente exigir que o tráfego de saída KMS passe por um proxy de encaminhamento HTTP. A configuração proxyOptions suporta apenas o protocolo SOCKS5 e não abrange este caso.
Para controlar como o driver se conecta a um host KMS, defina a opção kmsConnectCallback em seu objeto ClientEncryptionOptions ou seu objetoAutoEncryptionOptions . Ao definir esta opção, o driver chama sua chamada de resposta em vez de se conectar ao próprio host KMS. O chamada de resposta recebe as seguintes propriedades:
Propriedade | Descrição |
|---|---|
| O nome do host KMS que o driver deve acessar. |
| A porta do host KMS que o driver deve acessar. |
| O tempo restante no orçamento de tempo limite de operação do lado do cliente (CSOT) da operação, em milissegundos. Essa propriedade é |
| Um |
O exemplo a seguir define uma chamada de resposta que abre um túnel para o host KMS enviando uma solicitação HTTP CONNECT para um proxy e, em seguida, passa a chamada de resposta para uma instância ClientEncryption:
import * as net from "net"; const kmsConnectCallback = ({ host, port, timeoutMS, signal }) => new Promise((resolve, reject) => { // Opens a plain connection to the proxy, not to the KMS host. // Passing signal lets Node abort the connection attempt when the // driver's timeout budget expires. const socket = net.connect({ host: "proxy.example.com", port: 8080, signal }); // Applies the remaining CSOT budget to the proxy handshake, so that // a proxy that accepts the connection but never answers CONNECT // can't stall the operation. if (timeoutMS !== undefined) { socket.setTimeout(timeoutMS, () => { socket.destroy(); reject(new Error("Timed out waiting for the proxy")); }); } socket.once("error", reject); socket.once("connect", () => { // Asks the proxy to tunnel to the KMS host socket.write( `CONNECT ${host}:${port} HTTP/1.1\r\n` + `Host: ${host}:${port}\r\n\r\n` ); socket.once("data", chunk => { if (chunk.toString("utf8").startsWith("HTTP/1.1 200")) { // Clears the handshake timeout and returns the socket so that // the driver can perform the TLS handshake socket.setTimeout(0); resolve(socket); } else { socket.destroy(); reject(new Error("Proxy refused the CONNECT request")); } }); }); }); const clientEncryption = new ClientEncryption(keyVaultClient, { keyVaultNamespace, kmsProviders, kmsConnectCallback });
A propriedade signal se aplica à conexão com o proxy, e a propriedade timeoutMS se aplica à troca CONNECT. Um tempo limite de soquete permanece ativo após o término da troca CONNECT, portanto, limpe o tempo limite antes de resolver a promessa. Caso contrário, o tempo limite pode destruir o soquete enquanto o driver executa a negociação TLS.
O exemplo anterior é condensada para mostrar a sequência de chamadas. No código de produção, armazene em buffer a resposta do proxy até receber o final do bloco de cabeçalho, porque a resposta pode chegar em vários blocos.
Importante
As opções kmsConnectCallback e proxyOptions são mutuamente exclusivas. Se você definir kmsConnectCallback e especificar um valor proxyHost em proxyOptions, o driver gerará um MongoCryptInvalidArgumentError.