Chiffrement côté client au niveau du champ - Amazon DocumentDB

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Chiffrement côté client au niveau du champ

Le chiffrement au niveau du champ (FLE) côté client Amazon DocumentDB vous permet de crypter les données sensibles de vos applications clientes avant leur transfert vers un cluster Amazon DocumentDB. Les données sensibles restent chiffrées lorsqu'elles sont stockées et traitées dans un cluster et sont déchiffrées dans l'application cliente lors de leur récupération.

Démarrer

La configuration initiale du fichier FLE côté client dans Amazon DocumentDB est un processus en quatre étapes qui comprend la création d'une clé de chiffrement, l'association d'un rôle à l'application, la configuration de l'application et la définition du fonctionnement du CRUD à l'aide d'options de chiffrement.

Étape 1 : créer les clés de chiffrement

À l'aide deAWS Key Management Service, créez une clé symétrique utilisée pour crypter et déchiffrer le champ de données sensibles et fournissez-lui les autorisations d'utilisation IAM nécessaires. AWS KMSstocke la clé client (CK) qui est utilisée pour crypter les clés de données (DKs). Nous vous recommandons de stocker la clé client dans KMS pour renforcer votre sécurité. La clé de données est la clé secondaire qui est stockée dans une collection Amazon DocumentDB et qui est requise pour crypter les champs sensibles avant de stocker le document dans Amazon DocumentDB. La clé client chiffre la clé de données qui, à son tour, chiffre et déchiffre vos données. Si vous utilisez un cluster global, vous pouvez créer une clé multirégion qui peut être utilisée par différents rôles de service dans différentes régions.

Pour plus d'informations surAWS Key Management Service, notamment sur la création d'une clé, consultez le Guide du développeur du service de gestion desAWS clés.

Étape 2 : associer un rôle à l'application

créer une politique IAM avec desAWS KMS autorisations appropriées. Cette politique autorise les identités IAM auxquelles elle est attachée à chiffrer et déchiffrer la clé KMS spécifiée dans le champ de ressource. Votre application assume ce rôle IAM pour s'authentifierAWS KMS.

La politique doit être similaire à ceci :

{ "Effect": "Allow", "Action": ["kms:Decrypt", "kms:Encrypt"], "Resource": "Customer Key ARN" }

Étape 3 : Configurer l'application

Vous avez désormais défini une clé client dansAWS KMS, créé un rôle IAM et lui avez fourni les autorisations IAM appropriées pour accéder à la clé client. Importez les packages obligatoires.

import boto3 import json import base64 from pymongo import MongoClient from pymongo.encryption import (Algorithm, ClientEncryption)
# create a session object: my_session = boto3.session.Session() # get access_key and secret_key programmatically using get_frozen_credentials() method: current_credentials = my_session.get_credentials().get_frozen_credentials()
  1. Spécifiez « aws » comme type de fournisseur KMS et saisissez les informations d'identification de votre compte qui ont été récupérées à l'étape précédente.

    provider = "aws" kms_providers = { provider: { "accessKeyId": current_credentials.access_key, "secretAccessKey": current_credentials.secret_key } }
  2. Spécifiez la clé client utilisée pour chiffrer la clé de données :

    customer_key = { “region”: “AWS region of the customer_key”, “key”: “customer_key ARN” } key_vault_namespace = "encryption.dataKeys" key_alt_name = 'TEST_DATA_KEY'
  3. Configurez MongoClient l'objet :

    client = MongoClient(connection_string) coll = client.test.coll coll.drop() client_encryption = ClientEncryption( kms_providers, # pass in the kms_providers variable from the previous step key_vault_namespace = key_vault_namespace, client, coll.codec_options )
  4. Générez votre clé de données :

    data_key_id = client_encryption.create_data_key(provider, customer_key, key_alt_name = [key_alt_name])
  5. Récupérez votre clé de données existante :

    data_key = DataKey("aws", master_key = customer_key) key_id = data_key["_id"] data_key_id = client[key_vault_namespace].find_one({"_id": key_id})

Étape 4 : définir une opération CRUD

Définissez l'opération CRUD à l'aide des options de chiffrement.

  1. Définissez la collection pour écrire/lire/supprimer un seul document :

    coll = client.gameinfo.users
  2. Chiffrement explicite : cryptez les champs et insérez :

    Note

    Exactement l'un des termes « key_id » ou « key_alt_name » doit être fourni.

    encrypted_first_name = client_encryption.encrypt( "Jane", Algorithm.AEAD_AES_256_CBC_HMAC_SHA_512_Deterministic, key_alt_name=data_key_id ) encrypted_last_name = client_encryption.encrypt( "Doe", Algorithm.AEAD_AES_256_CBC_HMAC_SHA_512_Deterministic, key_alt_name=data_key_id ) encrypted_dob = client_encryption.encrypt( "1990-01-01", Algorithm.AEAD_AES_256_CBC_HMAC_SHA_512_Random, key_alt_name=data_key_id ) coll.insert_one( {"gamerTag": "jane_doe90", "firstName": encrypted_first_name, "lastName": encrypted_last_name, "dateOfBirth":encrypted_dob, "Favorite_games":["Halo","Age of Empires 2","Medal of Honor"] })

Exemple : fichier de configuration du chiffrement au niveau du champ côté client

Dans les exemples suivants, remplacez chaque espace réservé pour l'entrée utilisateur par vos propres informations.

# import python packages: import boto3 import json import base64 from pymongo import MongoClient from pymongo.encryption import (Algorithm, ClientEncryption) def main(): # create a session object: my_session = boto3.session.Session() # get aws_region from session object: aws_region = my_session.region_name # get access_key and secret_key programmatically using get_frozen_credentials() method: current_credentials = my_session.get_credentials().get_frozen_credentials() provider = "aws" # define the kms_providers which is later used to create the Data Key: kms_providers = { provider: { "accessKeyId": current_credentials.access_key, "secretAccessKey": current_credentials.secret_key } } # enter the kms key ARN. Replace the example ARN value. kms_arn = "arn:aws:kms:us-east-1:123456789:key/abcd-efgh-ijkl-mnop" customer_key = { "region": aws_region, "key":kms_arn } # secrets manager is used to strore and retrieve user credentials for connecting to an Amazon DocumentDB cluster. # retrieve the secret using the secret name. Replace the example secret key. secret_name = "/dev/secretKey" docdb_credentials = json.loads(my_session.client(service_name = 'secretsmanager', region_name = "us-east-1").get_secret_value(SecretId = secret_name)['SecretString']) connection_params = '/?tls=true&tlsCAFile=global-bundle.pem&replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false' conn_str = 'mongodb://' + docdb_credentials["username"] + ':' + docdb_credentials["password"] + '@' + docdb_credentials["host"] + ':' + str(docdb_credentials["port"]) + connection_params client = MongoClient(conn_str) coll = client.test.coll coll.drop() # store the encryption data keys in a key vault collection (having naming convention as db.collection): key_vault_namespace = "encryption.dataKeys" key_vault_db_name, key_vault_coll_name = key_vault_namespace.split(".", 1) # set up the key vault (key_vault_namespace) for this example: key_vault = client[key_vault_db_name][key_vault_coll_name] key_vault.drop() key_vault.create_index("keyAltNames", unique=True) client_encryption = ClientEncryption( kms_providers, key_vault_namespace, client, coll.codec_options) # create a new data key for the encrypted field: data_key_id = client_encryption.create_data_key(provider, master_key=customer_key, key_alt_names=["some_key_alt_name"], key_material = None) # explicitly encrypt a field: encrypted_first_name = client_encryption.encrypt( "Jane", Algorithm.AEAD_AES_256_CBC_HMAC_SHA_512_Deterministic, key_id=data_key_id ) coll.insert_one( {"gamerTag": "jane_doe90", "firstName": encrypted_first_name }) doc = coll.find_one() print('Encrypted document: %s' % (doc,)) # explicitly decrypt the field: doc["encryptedField"] = client_encryption.decrypt(doc["encryptedField"]) print('Decrypted document: %s' % (doc,)) # cleanup resources: client_encryption.close() client.close() if __name__ == "__main__": main()

Recherche dans un fichier FLE côté client

Amazon DocumentDB prend en charge les requêtes d'égalité de points avec un FLE côté client. Les requêtes d'inégalité et de comparaison peuvent renvoyer des résultats inexacts. Les opérations de lecture et d'écriture peuvent avoir un comportement inattendu ou incorrect par rapport à l'exécution de la même opération sur la valeur déchiffrée.

Par exemple, pour rechercher des filtres pour des documents dont le score de joueur est supérieur à 500 :

db.users.find( { "gamerscore" : { $gt : 500 } })

Le client utilise une méthode de cryptage explicite pour crypter la valeur de la requête :

encrypted_gamerscore_filter = client_encryption.encrypt( 500, Algorithm.AEAD_AES_256_CBC_HMAC_SHA_512_Deterministic, key_alt_name=data_key_id ) db.users.find( { "gamerscore" : { $gt : encrypted_gamerscore_filter } } )

Lors de l'opération de recherche, Amazon DocumentDB compare la valeur chiffrée de 500 aux valeurs des champs cryptés stockées dans chaque document à l'aide du contrôle des inégalités supérieures à. La vérification des inégalités dans l'opération de recherche peut renvoyer un résultat différent lorsqu'elle est effectuée à l'aide de données et de valeurs déchiffrées, même si l'opération réussit à générer des résultats.

Limites

Les limites suivantes s'appliquent au chiffrement au niveau du champ côté client Amazon DocumentDB :

  • Amazon DocumentDB prend uniquement en charge les requêtes d'égalité de points. Les requêtes d'inégalité et de comparaison peuvent renvoyer des résultats inexacts. Les opérations de lecture et d'écriture peuvent avoir un comportement inattendu ou incorrect par rapport à l'exécution de la même opération sur la valeur déchiffrée. Pour rechercher des filtres pour les documents dont le score de joueur est supérieur à 500.

    db.users.find( { "gamerscore" : { $gt : 500 } })

    Le client utilise une méthode de cryptage explicite pour crypter la valeur de la requête.

    encrypted_gamerscore_filter = client_encryption.encrypt( 500, Algorithm.AEAD_AES_256_CBC_HMAC_SHA_512_Deterministic, key_alt_name=data_key_id ) db.users.find({ "gamerscore" : { $gt : encrypted_gamerscore_filter } })

    Lors de l'opération de recherche, Amazon DocumentDB compare la valeur chiffrée de 500 aux valeurs des champs cryptés stockées dans chaque document à l'aide du contrôle des inégalités supérieures à. La vérification des inégalités dans l'opération de recherche peut renvoyer un résultat différent lorsqu'elle est effectuée à l'aide de données et de valeurs déchiffrées, même si l'opération réussit à générer des résultats.

  • Amazon DocumentDB ne prend pas en charge les fichiers FLE côté client explicites provenant du Mongo Shell. Toutefois, cette fonctionnalité fonctionne avec tous les pilotes pris en charge.