Todos os produtos
Search
Central de documentação

ApsaraDB for MongoDB:Use o recurso Queryable Encryption no MongoDB 7.0

Última atualização: Jun 26, 2026

O MongoDB 7.0 introduz o Queryable Encryption para cenários que exigem maior segurança de banco de dados.

Informações básicas

Os recursos de criptografia transparente de dados (TDE) e criptografia de disco do ApsaraDB for MongoDB são soluções de criptografia em repouso. Eles atendem às seguintes finalidades:

  • Proteção de dados: protege os dados nos discos contra acesso não autorizado. Mesmo que um usuário mal-intencionado tenha acesso físico aos HDDs ou SSDs onde os dados estão armazenados, ele não consegue acessar os dados não criptografados.

  • Prevenção de vazamentos: se um dispositivo de armazenamento for roubado ou perdido, a criptografia impede que usuários não autorizados acessem dados confidenciais.

  • Requisitos de conformidade: diversos padrões e regulamentos do setor exigem que as empresas criptografem dados sensíveis, como dados pessoais de usuários e informações financeiras. A criptografia em repouso ajuda as empresas a cumprir essas exigências regulatórias.

Nota

Os arquivos de backup de uma instância do ApsaraDB for MongoDB com TDE ou criptografia de disco ativada são criptografados.

Com a criptografia em repouso, os dados carregados na memória permanecem em texto simples. Para proteger totalmente seus dados, recomendamos implementar medidas de segurança adicionais, como criptografia de rede (SSL/TLS), controle de acesso ao banco de dados, auditoria e monitoramento. Para evitar riscos de segurança decorrentes de acesso interno de O&M às instâncias do Elastic Compute Service (ECS) que hospedam seus serviços de banco de dados, a Alibaba Cloud fornece autorização do cliente e auditoria obrigatória.

Caso necessite de proteção adicional além da criptografia em repouso, utilize o recurso Queryable Encryption lançado oficialmente no MongoDB 7.0.

Introdução

O Queryable Encryption foi disponibilizado como prévia no MongoDB 6.0 e lançado oficialmente no MongoDB 7.0.

O Queryable Encryption mantém os dados criptografados até que cheguem ao cliente. As consultas são enviadas ao servidor junto com a chave de criptografia gerenciada pelo Key Management Service (KMS). O servidor consulta e retorna os dados em texto cifrado. Após o retorno ao cliente, os dados são descriptografados com a chave e exibidos em texto simples.

O Queryable Encryption oferece as seguintes capacidades:

  • Criptografa dados sensíveis no lado do cliente. Somente o cliente pode obter a chave de criptografia.

  • Mantém a criptografia dos dados durante todo o ciclo de vida, incluindo transmissão, armazenamento, uso, auditoria e backup.

  • Suporta consultas expressivas em dados criptografados, incluindo consultas de igualdade, intervalo, prefixo, sufixo e substring.

  • Reforça a privacidade dos dados. Apenas usuários autorizados com acesso à aplicação no servidor e às chaves de criptografia podem visualizar os dados em texto simples.

  • Simplifica o desenvolvimento de aplicações. Os desenvolvedores podem usar as capacidades nativas de criptografia do banco de dados para garantir segurança e conformidade.

  • Reduz preocupações com segurança ao armazenar dados sensíveis no ApsaraDB for MongoDB.

O MongoDB Community Edition não suporta criptografia automática, o que o diferencia da Enterprise Edition (Atlas).

Para mais informações sobre versões de drivers e bancos de dados criptografados, consulte Compatibilidade do Queryable Encryption.

Limites

  • Comandos de diagnóstico e logs de consulta em uma coleção criptografada são redigidos ou ocultados, o que limita a análise de problemas:

    • Comandos aplicáveis a uma coleção criptografada, como aggregate, count, find, insert, update, and delete, não são registrados em logs de consulta lenta nem em profilers.

    • Os resultados de comandos de diagnóstico, como collStats, currentOp, top, or $planCacheStats, são redigidos e alguns campos ficam ocultos.

  • A contenção entre campos criptografados pode aumentar a latência de escrita. O fator de contenção padrão é 8.

  • Coleções de metadados que excedem 1 GB devem ser compactadas manualmente. Para mais detalhes, consulte Compactação de coleção de metadados.

  • O objeto encryptedFieldsMap não pode ser alterado, incluindo os campos de consulta nele contidos.

  • O Queryable Encryption é suportado apenas por instâncias de replica set ou sharded cluster.

  • Não é possível ler dados criptografados em nós secundários.

  • Documentos não podem ser atualizados em lote com o comando updateMany or bulkWrite, e os parâmetros no comando findAndModify são limitados.

  • A operação upsert não é suportada. Quando o upsert é acionado, campos criptografados não são inseridos.

  • A Criptografia no Nível de Campo do Lado do Cliente (CSFLE) e o Queryable Encryption não podem ser ativados na mesma coleção. Uma coleção com CSFLE ativado ou uma coleção não criptografada não pode ser convertida para uma coleção com Queryable Encryption.

  • O Queryable Encryption só pode ser ativado em novas coleções vazias.

  • Uma coleção que contém campos criptografados não pode ser renomeada, e os campos não podem ser renomeados com o comando $rename.

  • Se jsonSchema for especificado durante a criação de uma coleção criptografada, a palavra-chave encrypt não poderá ser incluída.

  • Views, coleções de séries temporais e coleções com limite de tamanho (capped collections) não são suportadas.

  • Índices TTL ou índices únicos não são suportados.

  • Não é possível desativar o jsonSchema.

  • Exclua a coleção usando um MongoClient com Queryable Encryption ativado. Caso contrário, os metadados permanecerão no servidor.

  • O Queryable Encryption não suporta collation. A collation bloqueia a ordenação normal de campos criptografados.

  • O campo _id não pode ser especificado como um campo criptografado.

  • Apenas um número limitado de comandos e operadores é suportado. Para mais informações, consulte Operações suportadas para Queryable Encryption.

Preparativos

Este guia utiliza uma instância ECS como cliente para demonstrar o procedimento. Se o seu ambiente de teste já possuir as dependências necessárias, ignore as etapas correspondentes. Este guia usa o driver Node.js para a demonstração porque o mongosh suporta apenas criptografia automática, enquanto o MongoDB Community Edition suporta apenas criptografia explícita.

  1. Instale o Node.js e o npm.

    curl -fsSL https://rpm.nodesource.com/setup_lts.x | sudo bash -
    sudo yum install nodejs
    node -v
    npm -v
  2. Instale o driver oficial do Node.js para MongoDB.

    mkdir node_quickstart
    cd node_quickstart
    npm init -y
    npm install mongodb@6.6
  3. Instale a biblioteca libmongocrypt.

    vi /etc/yum.repos.d/libmongocrypt.repo
    // Add the following content to the file:
    [libmongocrypt]
    name=libmongocrypt repository
    baseurl=https://libmongocrypt.s3.amazonaws.com/yum/redhat/8/libmongocrypt/1.8/x86_64
    gpgcheck=1
    enabled=1
    gpgkey=https://pgp.mongodb.com/libmongocrypt.asc
    // Install the library
    sudo yum install -y libmongocrypt
  4. Instale o pacote mongodb-client-encryption, do qual o driver Node.js depende.

    sudo yum groupinstall 'Development Tools'
    npm install mongodb-client-encryption
  5. Instale o mongosh e configure a variável de ambiente MONGODB_URI.

    wget https://repo.mongodb.org/yum/redhat/8/mongodb-org/7.0/x86_64/RPMS/mongodb-mongosh-2.2.5.x86_64.rpm
    yum install -y ./mongodb-mongosh-2.2.5.x86_64.rpm
    export MONGODB_URI="mongodb://root:xxxxxx@dds-2zef23cef14b4f142.mongodb.pre.rds.aliyuncs.com:3717,dds-2zef23cef14b4f141.mongodb.pre.rds.aliyuncs.com:3717/admin?replicaSet=mgset-855706"
    // Test the connection
    mongosh ${MONGODB_URI}
  6. Obtenha a biblioteca compartilhada de criptografia automática.

    No Download Center, selecione o cliente correspondente à sua máquina e versão de distribuição e escolha o pacote crypt_shared. Para mais informações, consulte Download do MongoDB Enterprise Server.

    // Decompress the local directory to obtain the lib/mongo_crypt_v1.so file.
    tar -xzvf mongo_crypt_shared_v1-linux-x86_64-enterprise-rhel80-7.0.9.tgz

Procedimento

Nota

O MongoDB Community Edition não suporta criptografia automática. Portanto, este artigo demonstra o processo de criptografia explícita.

Acesse o ambiente REPL do Node.js e execute as etapas a seguir:

node -i -e "const MongoClient = require('mongodb').MongoClient; const ClientEncryption = require('mongodb').ClientEncryption;"
  1. Crie uma chave mestra do cliente (CMK).

    Nota

    O exemplo a seguir mostra as configurações de amostra de um provedor KMS local. Recomendamos não usar essas configurações em ambiente de produção.

    Gere uma CMK de 96 bytes e armazene-a no arquivo customer-master-key.txt do sistema de arquivos local.

    const fs = require("fs");
    const crypto = require("crypto");
    try {
      fs.writeFileSync("customer-master-key.txt", crypto.randomBytes(96));
    } catch (err) {
      console.error(err);
    }

    Este exemplo gera a CMK usando uma chamada crypto do Node.js. Alternativamente, gere a CMK de 96 bytes em um shell usando /dev/urandom:

    echo $(head -c 96 /dev/urandom | base64 | tr -d '\n')
  2. Inicialize as variáveis.

    // KMS provider name should be one of the following: "aws", "gcp", "azure", "kmip" or "local"
    const kmsProviderName = "local";
    const uri = process.env.MONGODB_URI;
    const keyVaultDatabaseName = "encryption";
    const keyVaultCollectionName = "__keyVault";
    const keyVaultNamespace = "encryption.__keyVault";
    const encryptedDatabaseName = "medicalRecords";
    const encryptedCollectionName = "patients";

    No código de exemplo anterior, as seguintes variáveis são inicializadas:

    • kmsProviderName: o nome do provedor KMS. Neste exemplo, usa-se local.

    • uri: a URI do MongoDB. É possível definir a URI do MongoDB pela variável de ambiente MONGODB_URI ou especificá-la diretamente.

    • keyVaultDatabaseName: o nome do banco de dados que armazena as chaves de criptografia de dados (DEKs).

    • keyVaultCollectionName: o nome da coleção que armazena as DEKs. Esta coleção deve ser diferente de uma coleção regular.

    • keyVaultNamespace: equivale à variável keyVaultDatabaseName ou keyVaultCollectionName.

    • encryptedDatabaseName: o nome do banco de dados que armazena dados criptografados.

    • encryptedCollectionName: o nome da coleção que armazena dados criptografados.

  3. Crie um índice único na coleção que armazena as DEKs.

    const keyVaultClient = new MongoClient(uri);
    await keyVaultClient.connect();
    const keyVaultDB = keyVaultClient.db(keyVaultDatabaseName);
    // Delete the database with the same name as the database that stores DEKs to prevent excess data.
    await keyVaultDB.dropDatabase();
    const keyVaultColl = keyVaultDB.collection(keyVaultCollectionName);
    await keyVaultColl.createIndex(
      { keyAltNames: 1 },
      {
        unique: true,
        partialFilterExpression: { keyAltNames: { $exists: true } },
      }
    );
    // double check
    await keyVaultColl.indexes();
  4. Crie uma coleção criptografada.

    1. Obtenha a CMK criada e especifique o provedor KMS.

      const localMasterKey = fs.readFileSync("./customer-master-key.txt");
      kmsProviders = {local: {key: localMasterKey}};
    2. Crie uma DEK.

      Nota

      Antes de executar esta etapa, certifique-se de que o usuário especificado na variável uri tenha a permissão dbAdmin nos bancos de dados encryption._keyVault e medicalRecords.

      const clientEnc = new ClientEncryption(keyVaultClient, {
        keyVaultNamespace: keyVaultNamespace,
        kmsProviders: kmsProviders,
      });
      const dek1 = await clientEnc.createDataKey(kmsProviderName, {
        keyAltNames: ["dataKey1"],
      });
      const dek2 = await clientEnc.createDataKey(kmsProviderName, {
        keyAltNames: ["dataKey2"],
      });
    3. Especifique os campos a serem criptografados e configure a DEK criada.

      const encryptedFieldsMap = {
        [`${encryptedDatabaseName}.${encryptedCollectionName}`]: {
          fields: [
            {
              keyId: dek1,
              path: "patientId",
              bsonType: "int",
              queries: { queryType: "equality" },
            },
            {
              keyId: dek2,
              path: "medications",
              bsonType: "array",
            },
          ],
        },
      };
    4. Especifique a biblioteca compartilhada de criptografia automática e crie um MongoClient.

      const extraOptions = {cryptSharedLibPath: "/root/lib/mongo_crypt_v1.so"};
      const encClient = new MongoClient(uri, {
        autoEncryption: {
          keyVaultNamespace,
          kmsProviders,
          extraOptions,
          encryptedFieldsMap,
        },
      });
      await encClient.connect();
    5. Crie uma coleção criptografada.

      const newEncDB = encClient.db(encryptedDatabaseName);
      await newEncDB.dropDatabase();
      await newEncDB.createCollection(encryptedCollectionName);
  5. Crie um MongoClient para criptografar operações de leitura e escrita.

    1. Especifique a coleção que armazena a DEK criada.

      const eDB = "encryption";
      const eKV = "__keyVault";
      const keyVaultNamespace = `${eDB}.${eKV}`;
      const secretDB = "medicalRecords";
      const secretCollection = "patients";
    2. Especifique a CMK criada.

      Importante

      Não use o arquivo de chave local em ambiente de produção.

      const fs = require("fs");
      const path = "./customer-master-key.txt";
      const localMasterKey = fs.readFileSync(path);
      const kmsProviders = {
        local: {
          key: localMasterKey,
        },
      };
    3. Obtenha a DEK criada.

      Nota

      O nome da DEK deve ser idêntico ao nome da DEK criada na subetapa secundária da Etapa 4.

      const uri = process.env.MONGODB_URI;;
      const unencryptedClient = new MongoClient(uri);
      await unencryptedClient.connect();
      const keyVaultClient = unencryptedClient.db(eDB).collection(eKV);
      const dek1 = await keyVaultClient.findOne({ keyAltNames: "dataKey1" });
      const dek2 = await keyVaultClient.findOne({ keyAltNames: "dataKey2" });
    4. Especifique a biblioteca compartilhada de criptografia automática e crie um MongoClient.

      const extraOptions = {
        cryptSharedLibPath: "/root/lib/mongo_crypt_v1.so",
      };
      const encryptedClient = new MongoClient(uri, {
        autoEncryption: {
          kmsProviders: kmsProviders,
          keyVaultNamespace: keyVaultNamespace,
          bypassQueryAnalysis: true,
          keyVaultClient: unencryptedClient,
          extraOptions: extraOptions,
        },
      });
      await encryptedClient.connect();
    5. Crie um objeto ClientEncryption.

      const encryption = new ClientEncryption(unencryptedClient, {
        keyVaultNamespace,
        kmsProviders,
      });
  6. Insira um documento contendo campos criptografados na coleção criptografada criada.

    const patientId = 12345678;
    const medications = ["Atorvastatin", "Levothyroxine"];
    const indexedInsertPayload = await encryption.encrypt(patientId, {
      algorithm: "Indexed",
      keyId: dek1._id,
      contentionFactor: 1,
    });
    const unindexedInsertPayload = await encryption.encrypt(medications, {
      algorithm: "Unindexed",
      keyId: dek2._id,
    });
    const encryptedColl = encryptedClient.db(secretDB).collection(secretCollection);
    await encryptedColl.insertOne({
      firstName: "Jon",
      patientId: indexedInsertPayload,
      medications: unindexedInsertPayload,
    });
  7. Execute uma consulta no nível de campo na coleção criptografada criada.

    const findPayload = await encryption.encrypt(patientId, {
      algorithm: "Indexed",
      keyId: dek1._id,
      queryType: "equality",
      contentionFactor: 1,
    });
    console.log(await encryptedColl.findOne({ patientId: findPayload }));

    O exemplo a seguir mostra o documento retornado.

    > console.log(await encryptedColl.findOne({ patientId: findPayload }));
    {
      _id: new ObjectId('6645b56f58abf955ebd95caf'),
      firstName: 'Jon',
      patientId: 12345678,
      medications: [ 'Atorvastatin', 'Levothyroxine' ],
      __safeContent__: [
        Binary.createFromBase64('IrPf972hlhDvnasQH6rIAW6BqERo0ZEgC6C0/zNQiIY=', 0)
      ]
    }
  8. Utilize o cliente que contém opções criptografadas para acessar campos criptografados. Caso contrário, o acesso a esses campos não será possível.

    Use o cliente unencryptedClient, que não possui criptografia, para a consulta no nível de campo.

    console.log(await unencryptedClient.db(secretDB).collection(secretCollection).findOne());

    O exemplo a seguir mostra o documento retornado. Os campos sensíveis aparecem como dados binários.

    > console.log(await unencryptedClient.db(secretDB).collection(secretCollection).findOne());
    {
      _id: new ObjectId('6645b56f58abf955ebd95caf'),
      firstName: 'Jon',
      patientId: Binary.createFromBase64('DtmNrEDyTEBDidZxWkbGU/MQdYNxwmnqYj5tSr9uhHbwWj8bsSD3TWlZ8aMMvw6FY00cmdc1QLLoEX3NwlKRhz0zax9LcQhN3vKUf4eq3hAfBYWkyOQxsiwbPsU0AiXnMV+qM6J2p2JZGLrDvxfbTY+obBmRqdvlgJ51dKmYopvDNToWBXDQkqAis9/3vaGWE0+dqxAfqsgBboGoRGjRkSALoI7/M1CIhvmpds5LR7/232uI4f5QDbk0JVfjnI0Doov6b0GrAXe9', 6),
      medications: Binary.createFromBase64('EKqAnwBkWUBon0Qf9sZHVIkEphUdfDK/aqYPs5M1Xc58CkojwX0kvC+KjwYyEozia41F5cnD9NFBwnVuDJUaqjTLc1YwG1DEIUZdcYCMf3JiureqA0voYP3gZxPyFmf/h1DS80Jz+g', 6),
      __safeContent__: [
        Binary.createFromBase64('IrPf972hlhDvnasQH6rIAW6BqERo0ZEgC6CO/zNQiIY=', 0)
      ]
    }

    Também é possível usar o mongosh para acessar externamente os campos criptografados. Isso simula o acesso à coleção criptografada criada sem a chave do cliente.

    // In a separate terminal session, connect directly to the MongoDB URI with mongosh.
    mongosh ${MONGODB_URI}
    db.getSiblingDB("medicalRecords").patients.findOne()

    O exemplo a seguir mostra o documento retornado.

    mgset-855706 [primary] admin> db.getSiblingDB("medicalRecords").patients.findOne()
    {
      _id: ObjectId('6645b56f58abf955ebd95caf'),
      firstName: 'Jon',
      patientId: Binary.createFromBase64('DtmNrEDyTEBYDidZxWkbGU/MQdYNxwmnqYj5tSr9uhHbwWj8bsSD3TWlZ8aMMvw6fYO0cmdc1QLoEX3Nw1KRhz0zax9LcQhN3vKUf4eq3hAfBYWkyQxsiwbPsU0AiXnMV+qM6JZGLrDvxfbTY+obBmRqdvlJ51dKmYopvDNTowBXdQkqAis9/3vaGWEO+dqxAfqsgBboGoRGjRkSALoI7/M1CIhvmpds5LR7/232uI4f5QDbk0JVfjnIODoov6b0GrAXe9', 6),
      medications: Binary.createFromBase64('EKqAnwBkWUBon0Qf9sZHVIkEphUdfdk/aqYPs5M1Xc58CkojX0kvC+KjwYyEozia41F5cnD9NFBwnVuDJUaqjTLc1YwG1DEIUZdcYMf3liuregA0qvoYP3qZxPyFmf/h1IJz+g', 6),
      __safeContent__: [
        Binary.createFromBase64('IrPf972hlhDvnasQH6rIAW6BqERo0ZEgC6CO/zNQiIY=', 0)
      ]
    }

Referências