sql >> Base de Datos >  >> NoSQL >> MongoDB

Una descripción general del cifrado de nivel de campo del lado del cliente en MongoDB

Los datos a menudo requieren seguridad de alto nivel en casi todos los niveles de la transacción de datos para cumplir con las políticas de seguridad, el cumplimiento y las regulaciones gubernamentales. La reputación de la organización puede arruinarse si hay acceso no autorizado a datos confidenciales y, por lo tanto, no se cumple con el mandato descrito.

En este blog, analizaremos algunas de las medidas de seguridad que puede emplear con respecto a MongoDB, centrándonos especialmente en el lado del cliente.

Escenarios en los que se puede acceder a los datos

Hay varias formas en que alguien puede acceder a sus datos de MongoDB, estas son algunas de ellas...

  1. Captura de datos a través de una red insegura. Alguien puede acceder a sus datos a través de una API con una red VPN y será difícil rastrearlos. Los datos en reposo suelen ser los culpables en este caso.
  2. Un superusuario como un administrador que tiene acceso directo. Esto sucede cuando no define las funciones y restricciones de los usuarios.
  3. Tener acceso a datos en disco mientras lee bases de datos de archivos de copia de seguridad.
  4. Leyendo la memoria del servidor y los datos registrados.
  5. Divulgación accidental de datos por parte de un miembro del personal.

Categorías de datos de MongoDB y cómo se protegen

En general, cualquier sistema de base de datos implica dos tipos de datos: 

  1. Datos en reposo:uno que se almacena en los archivos de la base de datos
  2. Datos en tránsito:aquellos que se negocian entre un cliente, un servidor y la base de datos.

MongoDB tiene una función de cifrado en reposo que cifra los archivos de la base de datos en el disco y, por lo tanto, evita acceso a archivos de base de datos en disco.

Los datos en tránsito a través de una red se pueden proteger en MongoDB a través del cifrado de transporte utilizando TLS/SSL cifrando los datos.

En el caso de que un miembro del personal divulgue datos accidentalmente, por ejemplo, una recepcionista en la pantalla del escritorio, MongoDB integra el Control de acceso basado en roles que permite a los administradores otorgar y restringir permisos de nivel de colección para los usuarios.

Los datos transados ​​a través del servidor pueden permanecer en la memoria y estos enfoques en ningún momento abordan el problema de seguridad contra el acceso a los datos en la memoria del servidor. Por lo tanto, MongoDB introdujo el cifrado de nivel de campo del lado del cliente para cifrar campos específicos de un documento que involucran datos confidenciales.

Cifrado de nivel de campo

MongoDB funciona con documentos que tienen campos definidos. Es posible que se requiera que algunos campos contengan información confidencial, como el número de tarjeta de crédito, número de seguro social, datos de diagnóstico de paciencia y mucho más.

El cifrado de nivel de campo nos permitirá proteger los campos y solo el personal autorizado puede acceder a ellos con las claves de descifrado.

El cifrado se puede realizar de dos formas

  1. Usando una clave secreta. Se utiliza una única clave para cifrar y descifrar, por lo que debe presentarse en la transmisión de origen y de destino, pero todas las partes deben mantenerla en secreto.
  2. Usando una clave pública. Utiliza un par de claves en las que una se usa para cifrar y la otra para descifrar

Al aplicar el cifrado de nivel de campo, considere usar una nueva configuración de base de datos en lugar de una existente.

Cifrado de nivel de campo del lado del cliente (CSFLE)

Introducido en MongoDB versión 4.2 Enterprise para ofrecer a los administradores de bases de datos un ajuste para cifrar campos que involucran valores que deben protegerse. Es decir, los datos confidenciales son cifrados o descifrados por el cliente y solo se comunican hacia y desde el servidor de forma cifrada. Además, incluso los superusuarios que no tengan las claves de cifrado no tendrán control sobre estos campos de datos cifrados.

Cómo implementar CSFLE

Para implementar el cifrado de nivel de campo del lado del cliente, necesita lo siguiente:

  1. Servidor MongoDB 4.2 Enterprise
  2. MongoDB Compatible con CSFLE
  3. Permisos del sistema de archivos
  4. Controladores de idiomas específicos. (En nuestro blog vamos a utilizar Node.js)

El procedimiento de implementación involucra:

  • Un entorno de desarrollo local con un software para ejecutar cliente y servidor
  • Generar y validar las claves de cifrado.
  • Configurar el cliente para el cifrado automático a nivel de campo
  • A lo largo de las operaciones en términos de consultas de los campos encriptados.

Implementación de CSFLE

CSFLE utiliza la estrategia de cifrado de sobre mediante la cual las claves de cifrado de datos se cifran con otra clave conocida como clave maestra. La aplicación cliente crea una clave maestra que se almacena en el proveedor de claves local, esencialmente el sistema de archivos local. Sin embargo, este enfoque de almacenamiento no es seguro, por lo tanto, en producción, se recomienda configurar la clave en un sistema de administración de claves (KMS) que almacena y descifra las claves de cifrado de datos de forma remota.

Después de generar las claves de cifrado de datos, se almacenan en la colección de bóveda en el mismo conjunto de réplicas de MongoDB que los datos cifrados.

Crear clave maestra

En el nodo js, ​​necesitamos generar una clave maestra administrada localmente de 96 bytes y escribirla en un archivo en el directorio desde donde se ejecuta la secuencia de comandos principal: 

$npm install fs && npm install crypto

Luego en el guión:

const crypto = require(“crypto”)

const fs = require(“fs”)



try{

fs.writeFileSync(‘masterKey.txt’, crypto.randomBytes(96))

}catch(err){

throw err;

}

Crear clave de cifrado de datos

Esta clave se almacena en una colección de almacén de claves donde los clientes habilitados para CSFLE pueden acceder a la clave para el cifrado/descifrado. Para generar uno, necesita lo siguiente:

  • Clave maestra administrada localmente
  • Conexión a su base de datos, es decir, la cadena de conexión MongoDB
  • Espacio de nombres del almacén de claves (base de datos y colección)

Pasos para generar la clave de cifrado de datos

  1. Lea la clave maestra local generada antes

const localMasterKey = fs.readFileSync(‘./masterKey.txt’);
  1. Especifique la configuración del proveedor de KMS que usará el cliente para descubrir la clave maestra.

const kmsProvider = {

local: {

key: localMasterKey

}

}
  1. Creación de la clave de cifrado de datos. Necesitamos crear un cliente con la cadena de conexión de MongoDB y la configuración del espacio de nombres del almacén de claves. Digamos que tendremos una base de datos llamada usuarios y dentro de ella una colección de keyVault. Primero debe instalar uuid-base64 ejecutando el comando

$ npm install uuid-base64

Luego en su 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();

Luego se le presentará un resultado similar

DataKeyId [UUID]: ad4d735a-44789-48bc-bb93-3c81c3c90824

DataKeyId [base64]: 4K13FkSZSLy7kwABP4HQyD==

El cliente debe tener permisos de lectura y escritura en el espacio de nombres del almacén de claves especificado

 

  1. Para verificar que se creó la clave de cifrado de datos

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();

Debería recibir algún resultado por el estilo

{

  _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' }

}

Los datos del documento devuelto incluyen:ID de clave de cifrado de datos (UUID), clave de cifrado de datos en forma cifrada, información del proveedor de KMS de la clave maestra y metadatos como el día de creación.

Especificación de campos para cifrar utilizando el esquema JSON

Los controladores MongoDB utilizan una extensión JSON Schema para configurar el cifrado y descifrado automático del lado del cliente de los campos especificados de documentos en una colección. La configuración de CSFLE para este esquema requerirá:el algoritmo de cifrado a utilizar al cifrar cada campo, una o todas las claves de cifrado cifradas con la clave maestra de CSFLE y el tipo BSON de cada campo.

Sin embargo, este esquema CSFLE JSON no admite la validación de documentos; de lo contrario, cualquier instancia de validación hará que el cliente arroje un error.

Los clientes que no están configurados con el esquema JSON del lado del cliente adecuado pueden tener restricciones para escribir datos sin cifrar en un campo mediante el esquema JSON del lado del servidor.

Existen principalmente dos algoritmos de cifrado:Aleatorio y determinista.

Definiremos alguna clave encryptMetadata en el nivel raíz del esquema JSON y la configuraremos con los campos que se cifrarán definiéndolos en el campo de propiedades del esquema, por lo que podrán heredar esta clave de cifrado .

{

    "bsonType" : "object",

    "encryptMetadata" : {

        "keyId" : // keyId generated here

    },

    "properties": {

        // field schemas here

    }

}

Digamos que desea cifrar un campo de número de cuenta bancaria, haría algo como:

"bankAccountNumber": {

    "encrypt": {

        "bsonType": "int",

        "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"

    }

}

Debido a la alta cardinalidad y al campo consultable, usamos el enfoque determinista. Los campos confidenciales, como el tipo de sangre, que tienen un plan de consulta bajo y una cardinalidad baja, se pueden cifrar mediante el método aleatorio.

Los campos de matriz deben usar encriptación aleatoria con CSFLE para mejorar la encriptación automática de todos los elementos.

Aplicación Mongocryptd

Instalada en MongoDB Enterprise Service 4.2 y versiones posteriores, esta es una aplicación de cifrado independiente que automatiza el cifrado de nivel de campo del lado del cliente. Cada vez que se crea un cliente habilitado para CSFLE, este servicio se inicia automáticamente de forma predeterminada para:

  • Valide las instrucciones de cifrado descritas en el esquema JSON, detecte qué campos se cifrarán en las operaciones de rendimiento.
  • Evitar que se ejecuten operaciones no admitidas en los campos cifrados.

Para insertar los datos, haremos la consulta de inserción normal y el documento resultante tendrá datos de muestra a continuación con respecto al campo de la cuenta bancaria.

{

…

"bankAccountNumber":"Ac+ZbPM+sk7gl7CJCcIzlRAQUJ+uo/0WhqX+KbTNdhqCszHucqXNiwqEUjkGlh7gK8pm2JhIs/P3//nkVP0dWu8pSs6TJnpfUwRjPfnI0TURzQ==",

…

}

Cuando un personal autorizado realiza una consulta, el conductor descifrará estos datos y los devolverá en un formato legible, es decir, 

{

…

"bankAccountNumber":43265436456456456756,

…

}

Nota:  No es posible consultar documentos en un campo cifrado aleatoriamente a menos que utilice otro campo para encontrar el documento que contiene una aproximación de los datos del campo cifrado aleatoriamente.

Conclusión

La seguridad de los datos se debe considerar en todos los niveles con respecto a uno en reposo y tránsito. MongoDB Enterprise 4.2 Server ofrece a los desarrolladores una ventana para cifrar datos del lado del cliente utilizando el cifrado de nivel de campo del lado del cliente, por lo tanto, asegura los datos de los proveedores de host de la base de datos y el acceso inseguro a la red. CSFLE usa el cifrado de sobre donde se usa una clave maestra para cifrar las claves de cifrado de datos. Por lo tanto, la clave maestra debe mantenerse segura utilizando herramientas de gestión de claves como el Sistema de gestión de claves.