Os dados geralmente exigem segurança de ponta em quase todos os níveis da transação de dados para atender às políticas de segurança, conformidade e regulamentações governamentais. A reputação da organização pode ser arruinada se houver acesso não autorizado a dados confidenciais, portanto, o não cumprimento do mandato descrito.
Neste blog, discutiremos algumas das medidas de segurança que você pode empregar em relação ao MongoDB, especialmente com foco no lado do cliente.
Cenários em que os dados podem ser acessados
Existem várias maneiras de alguém acessar seus dados do MongoDB, aqui estão algumas delas...
- Captura de dados em uma rede insegura. Alguém pode acessar seus dados por meio de uma API com uma rede VPN e será difícil rastreá-los. Os dados em repouso geralmente são os culpados nesse caso.
- Um superusuário, como um administrador, com acesso direto. Isso acontece quando você não define as funções e restrições do usuário.
- Ter acesso a dados em disco durante a leitura de bancos de dados de arquivos de backup.
- Ler a memória do servidor e os dados registrados.
- Divulgação acidental de dados por funcionário.
Categorias de dados do MongoDB e como elas são protegidas
Em geral, qualquer sistema de banco de dados envolve dois tipos de dados:
- Dados em repouso:um que é armazenado nos arquivos de banco de dados
- Dados em trânsito:aqueles que são transacionados entre um cliente, servidor e o banco de dados.
MongoDB tem um recurso de Criptografia em Repouso que criptografa arquivos de banco de dados em disco, evitando acesso a arquivos de banco de dados em disco.
Dados em trânsito em uma rede podem ser protegidos no MongoDB por meio de criptografia de transporte usando TLS/SSL criptografando os dados.
No caso de dados serem divulgados acidentalmente por um membro da equipe, por exemplo, uma recepcionista na tela do desktop, o MongoDB integra o Controle de Acesso Baseado em Função que permite que os administradores concedam e restrinjam permissões de nível de coleção para usuários.
Os dados transacionados pelo servidor podem permanecer na memória e essas abordagens não abordam em nenhum momento a preocupação de segurança contra o acesso a dados na memória do servidor. O MongoDB, portanto, introduziu a Criptografia em Nível de Campo do Lado do Cliente para criptografar campos específicos de um documento que envolve dados confidenciais.
Criptografia em nível de campo
MongoDB trabalha com documentos que possuem campos definidos. Alguns campos podem ser necessários para manter informações confidenciais, como número do cartão de crédito, número do seguro social, dados de diagnóstico de paciência e muito mais.
A Criptografia em Nível de Campo nos permitirá proteger os campos e eles só podem ser acessados por pessoal autorizado com as chaves de descriptografia.
A criptografia pode ser feita de duas maneiras
- Usando uma chave secreta. Uma única chave é usada para criptografar e descriptografar, portanto, deve ser apresentada na transmissão de origem e destino, mas mantida em segredo por todas as partes.
- Usando uma chave pública. Usa um par de chaves em que uma é usada para criptografar e a outra usada para descriptografar
Ao aplicar a Criptografia em Nível de Campo, considere usar uma nova configuração de banco de dados em vez de uma existente.
Criptografia de nível de campo do lado do cliente (CSFLE)
Introduzido no MongoDB versão 4.2 Enterprise para oferecer aos administradores de banco de dados um ajuste para criptografar campos envolvendo valores que precisam ser protegidos. Ou seja, os dados confidenciais são criptografados ou descriptografados pelo cliente e apenas comunicados de e para o servidor de forma criptografada. Além disso, mesmo superusuários que não possuem as chaves de criptografia, não terão controle sobre esses campos de dados criptografados.
Como implementar o CSFLE
Para implementar a criptografia em nível de campo do lado do cliente, você precisa do seguinte:
- MongoDB Server 4.2 Enterprise
- MongoDB Compatível com CSFLE
- Permissões do sistema de arquivos
- Drivers de idioma específicos. (Em nosso blog, usaremos Node.js)
O procedimento de implementação envolve:
- Um ambiente de desenvolvimento local com um software para executar cliente e servidor
- Gerando e validando as chaves de criptografia.
- Configurando o cliente para criptografia automática em nível de campo
- Todas as operações em termos de consultas dos campos criptografados.
Implementação do CSFLE
CSFLE usa a estratégia de criptografia de envelope em que as chaves de criptografia de dados são criptografadas com outra chave conhecida como chave mestra. O aplicativo Cliente cria uma chave mestra que é armazenada no Provedor de Chave Local essencialmente no sistema de arquivos local. No entanto, essa abordagem de armazenamento é insegura, portanto, na produção, é aconselhável configurar a chave em um Sistema de Gerenciamento de Chave (KMS) que armazena e descriptografa chaves de criptografia de dados remotamente.
Depois que as chaves de criptografia de dados são geradas, elas são armazenadas na coleção de cofres no mesmo conjunto de réplicas do MongoDB que os dados criptografados.
Criar chave mestra
No node js, precisamos gerar uma chave mestra gerenciada localmente de 96 bytes e gravá-la em um arquivo no diretório de onde o script principal é executado:
$npm install fs && npm install crypto
Então no script:
const crypto = require(“crypto”)
const fs = require(“fs”)
try{
fs.writeFileSync(‘masterKey.txt’, crypto.randomBytes(96))
}catch(err){
throw err;
}
Criar chave de criptografia de dados
Esta chave é armazenada em uma coleção de cofre de chaves onde os clientes habilitados para CSFLE podem acessar a chave para criptografia/descriptografia. Para gerar um, você precisa do seguinte:
- Chave mestra gerenciada localmente
- Conexão com seu banco de dados, ou seja, a string de conexão do MongoDB
- Espaço de nomes do cofre de chaves (banco de dados e coleção)
Etapas para gerar a chave de criptografia de dados
-
Leia a chave mestra local gerada antes
const localMasterKey = fs.readFileSync(‘./masterKey.txt’);
-
Especifique as configurações do provedor KMS que serão usadas pelo cliente para descobrir a chave mestra.
const kmsProvider = {
local: {
key: localMasterKey
}
}
-
Criando a chave de criptografia de dados. Precisamos criar um cliente com a string de conexão do MongoDB e a configuração do namespace do cofre de chaves. Digamos que teremos um banco de dados chamado users e dentro dele uma coleção keyVault. Você precisa instalar o uuid-base64 primeiro executando o comando
$ npm install uuid-base64
Depois no seu script
const base64 = require('uuid-base64');
const keyVaultNamespace = 'users.keyVaul';
const client = new MongoClient('mongodb://localhost:27017', {
useNewUrlParser: true,
useUnifiedTopology: true,
});
async function createKey() {
try {
await client.connect();
const encryption = new ClientEncryption(client, {
keyVaultNamespace,
kmsProvider,
});
const key = await encryption.createDataKey('local');
const base64DataKeyId = key.toString('base64');
const uuidDataKeyId = base64.decode(base64DataKeyId);
console.log('DataKeyId [UUID]: ', uuidDataKeyId);
console.log('DataKeyId [base64]: ', base64DataKeyId);
} finally {
await client.close();
}
}
createKey();
Você será apresentado a algum resultado que se assemelha
DataKeyId [UUID]: ad4d735a-44789-48bc-bb93-3c81c3c90824
DataKeyId [base64]: 4K13FkSZSLy7kwABP4HQyD==
O cliente deve ter permissões ReadWrite no namespace do cofre de chaves especificado
-
Para verificar se a chave de criptografia de dados foi criada
const client = new MongoClient('mongodb://localhost:27017', {
useNewUrlParser: true,
useUnifiedTopology: true,
});
async function checkClient() {
try {
await client.connect();
const keyDB = client.db(users);
const keyColl = keyDB.collection(keyVault);
const query = {
_id: ‘4K13FkSZSLy7kwABP4HQyD==’,
};
const dataKey = await keyColl.findOne(query);
console.log(dataKey);
} finally {
await client.close();
}
}
checkClient();
Você deve receber algum resultado do tipo
{
_id: Binary {
_bsontype: 'Binary',
sub_type: 4,
position: 2,
buffer: <Buffer 68 ca d2 10 16 5d 45 bf 9d 1d 44 d4 91 a6 92 44>
},
keyMaterial: Binary {
_bsontype: 'Binary',
sub_type: 0,
position: 20,
buffer: <Buffer f1 4a 9f bd aa ac c9 89 e9 b3 da 48 72 8e a8 62 97 2a 4a a0 d2 d4 2d a8 f0 74 9c 16 4d 2c 95 34 19 22 05 05 84 0e 41 42 12 1e e3 b5 f0 b1 c5 a8 37 b8 ... 110 more bytes>
},
creationDate: 2020-02-08T11:10:20.021Z,
updateDate: 2020-02-08T11:10:25.021Z,
status: 0,
masterKey: { provider: 'local' }
}
Os dados do documento retornado incluem:ID da chave de criptografia de dados (UUID), chave de criptografia de dados em formato criptografado, informações do provedor KMS da chave mestra e metadados como dia de criação.
Especificando campos a serem criptografados usando o esquema JSON
Uma extensão de esquema JSON é usada pelos drivers do MongoDB para configurar a criptografia automática do lado do cliente e a descriptografia dos campos especificados de documentos em uma coleção. A configuração do CSFLE para esse esquema exigirá:o algoritmo de criptografia a ser usado ao criptografar cada campo, uma ou todas as chaves de criptografia criptografadas com a chave mestra CSFLE e o tipo BSON de cada campo.
No entanto, esse esquema CSFLE JSON não oferece suporte à validação de documentos, caso contrário, qualquer instância de validação fará com que o cliente gere um erro.
Os clientes que não estão configurados com o esquema JSON do lado do cliente apropriado podem ser impedidos de gravar dados não criptografados em um campo usando o esquema JSON do lado do servidor.
Existem principalmente dois algoritmos de criptografia:Aleatório e determinístico.
Vamos definir alguma chave encryptMetadata no nível raiz do esquema JSON e configurá-la com os campos a serem criptografados, definindo-os no campo de propriedades do esquema, portanto, eles poderão herdar essa chave de criptografia .
{
"bsonType" : "object",
"encryptMetadata" : {
"keyId" : // keyId generated here
},
"properties": {
// field schemas here
}
}
Digamos que você queira criptografar um campo de número de conta bancária, você faria algo como:
"bankAccountNumber": {
"encrypt": {
"bsonType": "int",
"algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
}
}
Devido à alta cardinalidade e ao campo que pode ser consultado, usamos a abordagem determinística. Campos confidenciais, como tipo sanguíneo, com baixo plano de consulta e baixa cardinalidade, podem ser criptografados usando a abordagem aleatória.
Os campos de matriz devem usar criptografia aleatória com CSFLE para aprimorar a criptografia automática de todos os elementos.
Aplicativo Mongocryptd
Instalado no MongoDB Enterprise Service 4.2 e posterior, este é um aplicativo de criptografia separado que automatiza a Criptografia em Nível de Campo do lado do cliente. Sempre que um cliente habilitado para CSFLE é criado, esse serviço é iniciado automaticamente por padrão para:
- Valide as instruções de criptografia descritas no esquema JSON, detecte quais campos devem ser criptografados nas operações de taxa de transferência.
- Evite a execução de operações sem suporte nos campos criptografados.
Para inserir os dados faremos a consulta normal de inserção e o documento resultante terá os dados de exemplo abaixo referentes ao campo conta bancária.
{
…
"bankAccountNumber":"Ac+ZbPM+sk7gl7CJCcIzlRAQUJ+uo/0WhqX+KbTNdhqCszHucqXNiwqEUjkGlh7gK8pm2JhIs/P3//nkVP0dWu8pSs6TJnpfUwRjPfnI0TURzQ==",
…
}
Quando um pessoal autorizado realiza uma consulta, o driver descriptografará esses dados e retornará em um formato legível, ou seja,
{
…
"bankAccountNumber":43265436456456456756,
…
}
Observação: não é possível consultar documentos em um campo criptografado aleatoriamente, a menos que você use outro campo para encontrar o documento que contém uma aproximação dos dados de campo criptografados aleatoriamente.
Conclusão
A segurança dos dados deve ser considerada em todos os níveis em relação a um em repouso e em trânsito. O MongoDB Enterprise 4.2 Server oferece aos desenvolvedores uma janela para criptografar dados do lado do cliente usando a criptografia de nível de campo do lado do cliente, protegendo os dados dos provedores de host do banco de dados e o acesso à rede inseguro. O CSFLE usa criptografia de envelope onde uma chave mestra é usada para criptografar chaves de criptografia de dados. A chave mestra deve, portanto, ser mantida em segurança usando ferramentas de gerenciamento de chaves, como o Sistema de Gerenciamento de Chaves.