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 no MongoDB 8.2 Notas de versão.
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();Importante
O estágio $rerank não é compatível com clientes configurados para criptografia automática usando criptografia no nível do campo do lado do cliente ou Queryable Encryption. Um pipeline que contém $rerank falha com um erro como Unrecognized pipeline stage name: '$rerank'.
A limitação se aplica a todas as coleção, incluindo coleção que não possuem campo criptografado, e ao uso de $rerank dentro de sub-pipeline, como $unionWith.
Roteie solicitações KMS através de um HTTP proxy
A partir da versão 7.6 do driver Node.js, você pode rotear as solicitações que o driver Node.js faz para o seu sistema de gerenciamento de chaves (KMS) por meio de um HTTP proxy. Use este recurso quando seu ambiente exigir que o tráfego KMS de saída passe por um proxy HTTP de encaminhamento. A configuração proxyOptions oferece suporte apenas ao protocolo SOCKS5 e não abrange este caso.
Para controlar como o driver se conecta a um hospedar KMS, defina a opção kmsConnectCallback em seu objeto ClientEncryptionOptions ou em seu objeto AutoEncryptionOptions. Quando você define esta opção, o driver chama sua chamada de resposta em vez de hospedar uma conexão com o próprio KMS. A chamada de resposta recebe as seguintes propriedades:
Propriedade | Descrição |
|---|---|
| O nome do host KMS que o driver deve alcançar. |
| A porta do hospedar KMS que o driver deve alcançar. |
| Obsoleto no driver Node.js 7.8 e posterior. Esta propriedade não tem efeito e está programada para ser removida em uma versão futura. Em versões anteriores do driver, ele continha o tempo restante no orçamento de tempo limite da operação do lado do cliente da operação, em milissegundos. |
| Um |
O exemplo a seguir define uma chamada de resposta que abre um túnel para o hospedar 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, 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 aborts the operation. const socket = net.connect({ host: "proxy.example.com", port: 8080, signal });
// Guards against a proxy that accepts the connection but stops // responding. The driver applies no timeout to the KMS connection, // so use an application-chosen idle timeout. It stays active after // the CONNECT exchange, so it also covers the TLS handshake and // KMS request that the driver performs over this socket. socket.setTimeout(10000, () => { socket.destroy(new Error("KMS connection timed out")); });
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")) { // Returns the socket so that the driver can perform the // TLS handshake 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. Quando a operação é abortada, o sinal é disparado e o nó interrompe a tentativa de conexão.
A chamar setTimeout() protege contra um proxy que aceita a conexão, mas para de responder. O driver não aplica nenhum tempo limite à kmsConnectCallback ou à solicitação KMS que se segue. Sem um tempo limite de inatividade que você escolher, a operação pode travar. O tempo limite é acionado se nenhum dado chegar no socket por 10 segundos. Ele permanece ativo após a troca CONNECT, portanto, também cobre o handshake TLS e a solicitação KMS que o driver envia pelo túnel. Quando o tempo limite é acionado, o exemplo passa um erro para socket.destroy(), que rejeita a operação pendente. O driver fecha o socket após cada solicitação KMS.
O exemplo anterior está condensado 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árias partes.
Importante
As opções kmsConnectCallback e proxyOptions são mutuamente exclusivas. Se você definir kmsConnectCallback e especificar um valor proxyHost em proxyOptions, o driver gera um MongoCryptInvalidArgumentError.