MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Un aperçu du chiffrement au niveau du champ côté client dans MongoDB

Les données nécessitent souvent une sécurité de haut niveau à presque tous les niveaux de la transaction de données afin de respecter les politiques de sécurité, la conformité et les réglementations gouvernementales. La réputation de l'organisation peut être ébranlée en cas d'accès non autorisé à des données sensibles, d'où le non-respect du mandat défini.

Dans ce blog, nous discuterons de certaines des mesures de sécurité que vous pouvez utiliser en ce qui concerne MongoDB, en nous concentrant en particulier sur le côté client.

Scénarios d'accès aux données

Il existe plusieurs façons d'accéder à vos données MongoDB, en voici quelques-unes...

  1. Capture de données sur un réseau non sécurisé. Quelqu'un peut accéder à vos données via une API avec un réseau VPN et il sera difficile de les retrouver. Les données au repos sont souvent les coupables dans ce cas.
  2. Un super utilisateur tel qu'un administrateur ayant un accès direct. Cela se produit lorsque vous ne parvenez pas à définir les rôles et les restrictions des utilisateurs.
  3. Avoir accès aux données sur disque lors de la lecture des bases de données des fichiers de sauvegarde.
  4. Lecture de la mémoire du serveur et des données enregistrées.
  5. Divulgation accidentelle de données par un membre du personnel.

Catégories de données MongoDB et comment elles sont sécurisées

En général, tout système de base de données implique deux types de données : 

  1. Données au repos :celles qui sont stockées dans les fichiers de la base de données
  2. Données en transit :données échangées entre un client, un serveur et la base de données.

MongoDB dispose d'une fonction de cryptage au repos qui crypte les fichiers de base de données sur le disque, empêchant ainsi accès aux fichiers de base de données sur disque.

Les données en transit sur un réseau peuvent être sécurisées dans MongoDB via Transport Encryption à l'aide de TLS/SSL en cryptant les données.

En cas de divulgation accidentelle de données par un membre du personnel, par exemple un réceptionniste sur un écran de bureau, MongoDB intègre le contrôle d'accès basé sur les rôles qui permet aux administrateurs d'accorder et de restreindre l'autorisation au niveau de la collection pour les utilisateurs.

Les données échangées sur le serveur peuvent rester en mémoire et ces approches ne résolvent à aucun moment le problème de sécurité contre l'accès aux données dans la mémoire du serveur. MongoDB a donc introduit le chiffrement au niveau du champ côté client pour chiffrer des champs spécifiques d'un document qui impliquent des données confidentielles.

Cryptage au niveau du champ

MongoDB fonctionne avec des documents qui ont des champs définis. Certains champs peuvent être nécessaires pour contenir des informations confidentielles telles que le numéro de carte de crédit, le numéro de sécurité sociale, les données de diagnostic de la patience et bien plus encore.

Field Level Encryption nous permettra de sécuriser les champs et ils ne seront accessibles que par un personnel autorisé avec les clés de déchiffrement.

Le chiffrement peut être effectué de deux manières

  1. Utilisation d'une clé secrète. Une clé unique est utilisée à la fois pour le chiffrement et le déchiffrement, elle doit donc être présentée à la source et à la destination de transmission mais gardée secrète par toutes les parties.
  2. Utilisation d'une clé publique. Utilise une paire de clés, l'une servant à chiffrer et l'autre à déchiffrer

Lors de l'application du chiffrement au niveau du champ, envisagez d'utiliser une nouvelle configuration de base de données plutôt qu'une existante.

Chiffrement au niveau du champ côté client (CSFLE)

Introduit dans MongoDB version 4.2 Enterprise pour offrir aux administrateurs de base de données un ajustement pour chiffrer les champs impliquant des valeurs qui doivent être sécurisées. C'est-à-dire que les données sensibles sont cryptées ou décryptées par le client et communiquées uniquement vers et depuis le serveur sous une forme cryptée. De plus, même les super utilisateurs qui ne disposent pas des clés de cryptage n'auront aucun contrôle sur ces champs de données cryptés.

Comment implémenter CSFLE

Pour que vous puissiez implémenter le chiffrement au niveau du champ côté client, vous avez besoin des éléments suivants :

  1. MongoDB Server 4.2 Entreprise
  2. MongoDB Compatible avec CSFLE
  3. Autorisations du système de fichiers
  4. Pilotes de langage spécifiques. (Dans notre blog, nous allons utiliser Node.js)

La procédure de mise en œuvre implique :

  • Un environnement de développement local avec un logiciel pour exécuter le client et le serveur
  • Génération et validation des clés de chiffrement.
  • Configuration du client pour le chiffrement automatique au niveau du champ
  • Tout au long des opérations en termes de requêtes des champs chiffrés.

Implémentation CSFLE

CSFLE utilise la stratégie de chiffrement d'enveloppe dans laquelle les clés de chiffrement des données sont chiffrées avec une autre clé appelée clé principale. L'application client crée une clé principale qui est stockée dans le fournisseur de clé local, essentiellement le système de fichiers local. déchiffre les clés de chiffrement des données à distance.

Une fois les clés de chiffrement des données générées, elles sont stockées dans la collection du coffre-fort dans le même jeu de répliques MongoDB que les données chiffrées.

Créer la clé principale

Dans le nœud js, nous devons générer une clé principale de 96 octets gérée localement et l'écrire dans un fichier du répertoire à partir duquel le script principal est exécuté : 

$npm install fs && npm install crypto

Puis dans le script :

const crypto = require(“crypto”)

const fs = require(“fs”)



try{

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

}catch(err){

throw err;

}

Créer une clé de chiffrement de données

Cette clé est stockée dans une collection de coffres de clés où les clients compatibles CSFLE peuvent accéder à la clé pour le chiffrement/déchiffrement. Pour en générer un, vous avez besoin des éléments suivants :

  • Clé principale gérée localement
  • Connexion à votre base de données, c'est-à-dire la chaîne de connexion MongoDB
  • Espace de noms de coffre de clés (base de données et collection)

Étapes pour générer la clé de chiffrement des données

  1. Lire la clé principale locale générée avant

const localMasterKey = fs.readFileSync(‘./masterKey.txt’);
  1. Spécifiez les paramètres du fournisseur KMS qui seront utilisés par le client pour découvrir la clé principale.

const kmsProvider = {

local: {

key: localMasterKey

}

}
  1. Création de la clé de chiffrement des données. Nous devons créer un client avec la chaîne de connexion MongoDB et la configuration de l'espace de noms du coffre de clés. Disons que nous aurons une base de données appelée utilisateurs et à l'intérieur une collection keyVault. Vous devez d'abord installer uuid-base64 en exécutant la commande

$ npm install uuid-base64

Puis dans votre 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();

Vous serez alors présenté avec un résultat qui ressemble

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

DataKeyId [base64]: 4K13FkSZSLy7kwABP4HQyD==

Le client doit disposer des autorisations ReadWrite sur l'espace de noms de coffre de clés spécifié

 

  1. Pour vérifier que la clé de chiffrement des données a été créée

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

Vous devriez recevoir un résultat du tri

{

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

}

Les données de document renvoyées comprennent :l'identifiant de la clé de cryptage des données (UUID), la clé de cryptage des données sous forme cryptée, les informations du fournisseur KMS sur la clé principale et les métadonnées telles que le jour de création.

Spécification des champs à chiffrer à l'aide du schéma JSON

Une extension de schéma JSON est utilisée par les pilotes MongoDB pour configurer le chiffrement et le déchiffrement automatiques côté client des champs spécifiés des documents d'une collection. La configuration CSFLE pour ce schéma nécessitera :l'algorithme de chiffrement à utiliser lors du chiffrement de chaque champ, une ou toutes les clés de chiffrement chiffrées avec la clé principale CSFLE et le type de BSON de chaque champ.

Cependant, ce schéma CSFLE JSON ne prend pas en charge la validation de document, sinon toute instance de validation entraînera une erreur du client.

Les clients qui ne sont pas configurés avec le schéma JSON côté client approprié peuvent être empêchés d'écrire des données non chiffrées dans un champ en utilisant le schéma JSON côté serveur.

Il existe principalement deux algorithmes de chiffrement :aléatoire et déterministe.

Nous allons définir une clé encryptMetadata au niveau racine du schéma JSON et la configurer avec les champs à chiffrer en les définissant dans le champ des propriétés du schéma afin qu'ils puissent hériter de cette clé de chiffrement .

{

    "bsonType" : "object",

    "encryptMetadata" : {

        "keyId" : // keyId generated here

    },

    "properties": {

        // field schemas here

    }

}

Supposons que vous souhaitiez chiffrer un champ de numéro de compte bancaire, vous feriez quelque chose comme :

"bankAccountNumber": {

    "encrypt": {

        "bsonType": "int",

        "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"

    }

}

En raison de la cardinalité élevée et du fait que le champ est interrogeable, nous utilisons l'approche déterministe. Les champs sensibles tels que le groupe sanguin qui ont un faible plan de requête et une faible cardinalité peuvent être chiffrés à l'aide de l'approche aléatoire.

Les champs de tableau doivent utiliser un chiffrement aléatoire avec CSFLE pour améliorer le chiffrement automatique de tous les éléments.

Application Mongocryptd

Installé dans MongoDB Enterprise Service 4.2 et versions ultérieures, il s'agit d'une application de chiffrement distincte qui automatise le chiffrement au niveau du champ côté client. Chaque fois qu'un client compatible CSFLE est créé, ce service est automatiquement démarré par défaut pour :

  • Valider les instructions de chiffrement décrites dans le schéma JSON, détecter les champs à chiffrer dans les opérations de débit.
  • Empêcher l'exécution d'opérations non prises en charge sur les champs chiffrés.

Pour insérer les données, nous ferons la requête d'insertion normale et le document résultant contiendra des exemples de données ci-dessous en ce qui concerne le champ du compte bancaire.

{

…

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

…

}

Lorsqu'un personnel autorisé effectue une requête, le conducteur déchiffre ces données et les renvoie dans un format lisible, c'est-à-dire 

{

…

"bankAccountNumber":43265436456456456756,

…

}

Remarque :  Il n'est pas possible d'interroger des documents sur un champ chiffré de manière aléatoire, sauf si vous utilisez un autre champ pour trouver le document qui contient une approximation des données de champ chiffrées de manière aléatoire.

Conclusion

La sécurité des données doit être prise en compte à tous les niveaux en ce qui concerne celui au repos et en transit. MongoDB Enterprise 4.2 Server offre aux développeurs une fenêtre pour chiffrer les données côté client à l'aide du chiffrement au niveau du champ côté client, sécurisant ainsi les données des fournisseurs d'hébergement de base de données et l'accès réseau non sécurisé. CSFLE utilise le chiffrement d'enveloppe où une clé principale est utilisée pour chiffrer les clés de chiffrement des données. La clé principale doit donc être conservée en toute sécurité à l'aide d'outils de gestion de clés tels que le système de gestion des clés.