Cifrado a nivel de campo del lado del cliente - Amazon DocumentDB

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

Cifrado a nivel de campo del lado del cliente

El cifrado a nivel de campo (FLE) del lado del cliente de Amazon DocumentDB le permite cifrar los datos confidenciales de las aplicaciones cliente antes de transferirlos a un clúster de Amazon DocumentDB. Los datos confidenciales permanecen cifrados cuando se almacenan y procesan en un clúster y se descifran en la aplicación cliente cuando se recuperan.

Introducción

La configuración inicial del FLE del lado del cliente en Amazon DocumentDB es un proceso de cuatro pasos que incluye la creación de una clave de cifrado, la asociación de un rol a la aplicación, la configuración de la aplicación y la definición de la operación CRUD con las opciones de cifrado.

Paso 1: crear las claves de cifrado

Con AWS Key Management Service, cree una clave simétrica que se utilice para cifrar y descifrar el campo de datos confidenciales y asígnele los permisos de uso de IAM necesarios. AWS KMS almacena la clave de cliente (CK) que se utiliza para cifrar las claves de datos (DK). Recomendamos almacenar la clave de cliente en KMS para reforzar su postura de seguridad. La clave de datos es la clave secundaria que se almacena en una colección de Amazon DocumentDB y se requiere para cifrar los campos confidenciales antes de almacenar el documento en Amazon DocumentDB. La clave de cliente cifra la clave de datos, que a su vez cifra y descifra sus datos. Si utiliza un clúster global, puede crear una clave multirregional que puedan utilizar distintos roles de servicio en distintas regiones.

Para obtener más información sobre la AWS Key Management Service, incluida la forma de crearla, consulte la Guía para desarrolladores del Servicio de administración de claves de AWS.

Paso 2: asociar un rol a la aplicación

Crear una política de IAM con permisos de AWS KMS apropiados. Esta política permite a las identidades de IAM a las que está asociada obtener y descifrar la clave KMS especificada en el campo de recursos. La aplicación asume este rol de IAM para autenticarse con AWS KMS.

El aspecto de la respuesta debe ser parecido al siguiente:

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

Paso 3: configurar la aplicación

A estas alturas, ya ha definido una clave de cliente en AWS KMS, ha creado una función de rol de IAM y le ha otorgado los permisos de IAM correctos para acceder a la clave de cliente. Importe estos paquetes necesarios.

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. Especifique “aws” como tipo de proveedor de KMS e introduzca las credenciales de su cuenta, que se recuperaron en el paso anterior.

    provider = "aws" kms_providers = { provider: { "accessKeyId": current_credentials.access_key, "secretAccessKey": current_credentials.secret_key } }
  2. Especifique la clave del cliente que se utiliza para cifrar la clave de datos:

    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. Configure el objeto MongoClient:

    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. Genere su clave de datos:

    data_key_id = client_encryption.create_data_key(provider, customer_key, key_alt_name = [key_alt_name])
  5. Recupera tu clave de datos existente:

    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})

Paso 4: definir una operación CRUD

Defina la operación CRUD con opciones de cifrado.

  1. Defina la colección para escribir/leer/eliminar un solo documento:

    coll = client.gameinfo.users
  2. Cifrado explícito: cifra los campos e inserta:

    nota

    Debe proporcionarse exactamente uno de los siguientes valores: “key_id” o “key_alt_name”.

    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"] })

Ejemplo: archivo de configuración de cifrado a nivel de campo del lado del cliente

En el siguiente ejemplo, reemplace cada marcador de posición del usuario con su propia información.

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

Consultas en el FLE del lado del cliente

Amazon DocumentDB admite consultas de igualdad de puntos con FLE del lado del cliente. Las consultas de desigualdad y comparación pueden arrojar resultados imprecisos. Las operaciones de lectura y escritura pueden tener un comportamiento inesperado o incorrecto en comparación con ejecutar la misma operación con el valor descifrado.

Por ejemplo, para consultar los filtros de documentos con una puntuación de jugador superior a 500:

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

El cliente utiliza un método de cifrado explícito para cifrar el valor de la consulta:

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 } } )

En la operación de búsqueda, Amazon DocumentDB compara el valor cifrado de 500 con los valores de campo cifrados almacenados en cada documento mediante la comprobación superior a la desigualdad. La comprobación de desigualdad de la operación de búsqueda puede arrojar un resultado diferente si se realiza con datos y valores descifrados, aunque la operación genere resultados satisfactoriamente.

Limitaciones

Las siguientes limitaciones se aplican al cifrado a nivel de campo del lado del cliente de Amazon DocumentDB:

  • Amazon DocumentDB solo admite consultas de igualdad de puntos. Las consultas de desigualdad y comparación pueden arrojar resultados imprecisos. Las operaciones de lectura y escritura pueden tener un comportamiento inesperado o incorrecto en comparación con ejecutar la misma operación con el valor descifrado. Para consultar los filtros de documentos con una puntuación de jugador superior a 500.

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

    El cliente utiliza un método de cifrado explícito para cifrar el valor de la consulta.

    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 } })

    En la operación de búsqueda, Amazon DocumentDB compara el valor cifrado de 500 con los valores de campo cifrados almacenados en cada documento mediante la comprobación superior a la desigualdad. La comprobación de desigualdad de la operación de búsqueda puede arrojar un resultado diferente si se realiza con datos y valores descifrados, aunque la operación genere resultados satisfactoriamente.

  • Amazon DocumentDB no admite el FLE explícito del lado del cliente desde el intérprete de comandos Mongo. Sin embargo, la característica funciona con cualquiera de nuestros controladores compatibles.