En esta guía, puede aprender a administrar sus claves de cifrado con un sistema de administración de claves (KMS) en tu aplicación habilitada para Encriptación de Nivel de Campo en el Lado del Cliente (CSFLE).
Componentes de cifrado
MongoDB utiliza los siguientes componentes para realizar el cifrado del lado del cliente a nivel de campo:
Llaves de cifrado de datos (DEK)
Llaves maestras de cliente (CMK)
Colecciones de Bóvedas de Llaves
Sistemade gestión de claves (KMS)
Para obtener más información sobre claves y bóvedas de claves, consulte Claves de cifrado y bóvedas de claves.
Servicios de gestión de claves compatibles
El cifrado a nivel de campo del lado del cliente admite los siguientes proveedores de sistemas de administración de claves:
Amazon Web Services KMS
Azure Key Vault
Google Cloud KMS
Cualquier sistema de gestión de claves compatible con KMIP.
Proveedor de claves local
La versión por defecto del protocolo KMIP es la 1.2. Puedes configurar MongoDB para usar la versión 1.0 o 1.1 de KMIP en el archivo de configuración de MongoDB Server.
Para obtener más información sobre estos proveedores, incluidos diagramas que muestran cómo su aplicación los utiliza para realizar el cifrado a nivel de campo del lado del cliente, consulte Proveedores de KMS.
Gestionar el nombre alternativo de una clave de cifrado de datos
Puedes asignar nombres alternativos a una llave de cifrado de datos para que sea más fácil de referenciar. Asignar nombres alternativos te permite realizar las siguientes acciones:
Haz referencia a un DEK por medios distintos a los del
_id.Asignar DEK dinámicamente en tiempo de ejecución.
Crea una llave de cifrado de datos con un nombre alternativo
Importante
Requisito previo
Antes de añadir un nuevo nombre alternativo de clave, debe crear un índice único parcial en el campo keyAltNames. Este índice debe tener un partialFilterExpression para los documentos donde exista keyAltNames.
El cifrado a nivel de campo del lado del cliente depende de la exclusividad de los nombres alternativos de claves impuesta por el servidor.
Para aprender cómo crear un índice parcial, consulta Índices Parciales.
El siguiente ejemplo crea una llave de cifrado de datos con un nombre alternativo. Seleccione la pestaña que corresponde a su lenguaje de driver:
var autoEncryptionOpts = { keyVaultNamespace: keyVaultNamespace, kmsProviders: kmsProviders, }; var encryptedClient = Mongo( connectionString, autoEncryptionOpts ); var clientEncryption = encryptedClient.getClientEncryption(); var masterKey = { "<Your dataKeyOpts Key>": "<Your dataKeyOpts Value>", }; var keyVault = encryptedClient.getKeyVault(); var keyId = keyVault.createKey("aws", masterKey, ["<Your Key Alt Name>"]);
var keyVaultClient = new MongoClient(connectionString); var clientEncryptionOptions = new ClientEncryptionOptions( keyVaultClient: keyVaultClient, keyVaultNamespace: keyVaultNamespace, kmsProviders: kmsProviders); var clientEncryption = new ClientEncryption(clientEncryptionOptions); var dataKeyOptions = new DataKeyOptions( alternateKeyNames: new[] { "<Your Key Alt Name>" }, masterKey: new BsonDocument { { "<Your dataKeyOpts Keys>", "<Your dataKeyOpts Values>" }, }); var dataKeyId = clientEncryption.CreateDataKey("<Your KMS Provider>", dataKeyOptions, CancellationToken.None);
clientEncryptionOpts := options.ClientEncryption().SetKeyVaultNamespace(KeyVaultNamespace).SetKmsProviders(kmsProviders) keyVaultClient, err := mongo.Connect(context.TODO(), options.Client().ApplyURI(URI)) if err != nil { return fmt.Errorf("Client connect error %v", err) } clientEnc, err := mongo.NewClientEncryption(keyVaultClient, clientEncryptionOpts) if err != nil { return fmt.Errorf("NewClientEncryption error %v", err) } defer func() { _ = clientEnc.Close(context.TODO()) }() masterKey := map[string]interface{}{ "<Your dataKeyOpts Key>": "<Your dataKeyOpts Value>", } dataKeyOpts := options.DataKey(). SetMasterKey(masterKey). SetKeyAltNames([]string{"<Your Key Alt Name>"}) dataKeyID, err := clientEnc.CreateDataKey(context.TODO(), provider, dataKeyOpts) if err != nil { return fmt.Errorf("create data key error %v", err) }
ClientEncryptionSettings clientEncryptionSettings = ClientEncryptionSettings.builder() .keyVaultMongoClientSettings(MongoClientSettings.builder() .applyConnectionString(new ConnectionString(connectionString)) .build()) .keyVaultNamespace(keyVaultNamespace) .kmsProviders(kmsProviders) .build(); ClientEncryption clientEncryption = ClientEncryptions.create(clientEncryptionSettings); BsonDocument masterKeyProperties = new BsonDocument(); masterKeyProperties.put("provider", new BsonString("<Your KMS Provider>")); masterKeyProperties.put("<Your dataKeyOpts Key>", new BsonString("<Your dataKeyOpts Value>")); List keyAltNames = new ArrayList<String>(); keyAltNames.add("<Your Key Alt Name>"); BsonBinary dataKeyId = clientEncryption.createDataKey(kmsProvider, new DataKeyOptions().masterKey(masterKeyProperties).keyAltNames(keyAltNames));
const encryption = new ClientEncryption(client, { keyVaultNamespace, kmsProviders, }); const masterKey = { "<Your dataKeyOpts Key>": "<Your dataKeyOpts Value>", }; const key = await encryption.createDataKey(provider, { masterKey: masterKey, keyAltNames: ["<Your Key Alt Name>"], });
client = MongoClient(connection_string) client_encryption = ClientEncryption( kms_providers, key_vault_namespace, client, CodecOptions(uuid_representation=STANDARD), ) master_key={ "<Your dataKeyOpts Key>" : "<Your dataKeyOpts Value>"} data_key_id = client_encryption.create_data_key(provider, master_key, key_alt_names=["<Your Key Alt Name>"])
Para obtener más información sobre los objetos dataKeyOpts y kmsProviders, consulta Proveedores KMS.
Usar nombres alternativos de clave en un esquema de cifrado automático
Los esquemas de cifrado contienen reglas especificadas por el usuario que identifican qué campos deben cifrarse y cómo cifrarlos. En tus reglas de cifrado, puedes especificar nombres de clave alternativos para la llave de cifrado de datos que cifra tu campo.
Debes hacer referencia a un nombre alternativo de clave con un puntero JSON. Usa punteros JSON para hacer referencia a un campo en tu consulta o documento de actualización que contenga el valor de tu nombre alternativo de clave.
Importante
No se puede usar un nombre alternativo para un campo cifrado de forma determinista
No se puede hacer referencia a una DEK por su nombre alternativo al cifrar un campo con el algoritmo de cifrado determinista. Para cifrar tu campo de manera determinista, debes especificar el _id de la clave que deseas utilizar para cifrar tu campo.
Referencia Clave Nombre alternativo en un esquema de cifrado
Considera el siguiente esquema de cifrado que cifra el campo salary:
{ "<database>.<collection>": { "bsonType": "object", "properties": { "salary": { "encrypt": { "bsonType": "int", "keyId": "/fieldWithAltName", "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" } } } } }
El campo keyId del esquema contiene un puntero JSON para hacer referencia al campo fieldWithAltName dentro de los documentos que se están cifrando.
El valor de fieldWithAltName del siguiente documento es my-alt-name:
{ "name": "Jon Doe", "salary": 45000, "fieldWithAltName": "my-alt-name" }
El salary campo está cifrado por la DEK que tiene el nombre my-alt-name alternativo.
Asignar claves dinámicamente en tiempo de ejecución
Puede usar nombres de clave alternativos para configurar dinámicamente la clave de cifrado de datos de un campo en tiempo de ejecución. Utilice esta función para cifrar documentos individuales con diferentes claves de cifrado de datos (DEK) utilizando el mismo esquema de cifrado.
Por ejemplo, considere los siguientes documentos:
{ "name": "Jon Doe", "salary": 45000, "fieldWithAltName": "my-alt-name" }, { "name": "Jane Smith", "salary": 70000, "fieldWithAltName": "my-other-alt-name" }
Inserta los documentos anteriores usando un cliente habilitado para CSFLE configurado con el esquema de cifrado de Ejemplo anterior.
En el esquema de cifrado, el salary.encrypt.keyId campo contiene un puntero JSON al fieldWithAltName campo del documento insertado. Como resultado, los salary campos de los dos documentos de ejemplo se cifran con una clave DEK específica para cada documento. Las claves se asignan dinámicamente en tiempo de ejecución.
Procedimiento: Rotar llaves de cifrado con Mongo Shell
Con la versión 1.5 y posteriores de Mongo Shell, puede rotar las claves de cifrado mediante el método rewrapManyDataKey. El método rewrapManyDataKey descifra automáticamente varias claves de datos y las vuelve a cifrar utilizando una clave maestra de cliente específica. A continuación, actualiza las claves rotadas en la colección del almacén de claves. Este método permite rotar las claves de cifrado basándose en dos argumentos opcionales:
Un filtro que se utiliza para especificar las claves que se rotarán. Si ninguna clave de datos coincide con el filtro especificado, no se rotará ninguna clave. Omita el filtro para rotar todas las claves de su colección de almacén de claves.
Un objeto que representa una nueva CMK. Omítalo para rotar las claves de datos usando sus CMK actuales.
El rewrapManyDataKey utiliza la siguiente sintaxis:
keyVault = db.getKeyVault() keyVault.rewrapManyDataKey( { "<Your custom filter>" }, { provider: "<KMS provider>", masterKey: { "<dataKeyOpts Key>" : "<dataKeyOpts Value>" } } )
Para obtener más información sobre el dataKeyOpts objeto para su proveedor de KMS,consulte Servicios de administración de claves compatibles.
Borrar una llave de cifrado de datos
Puede eliminar una llave de cifrado de datos de tu colección Key Vault usando las operaciones CRUD estándar de operaciones de eliminación. Si eliminas un DEK, todos los campos cifrados con ese DEK se vuelven permanentemente ilegibles.
Tip
Funcionalidad específica de MongoDB Shell
El shell de MongoDB le permite eliminar un DEK mediante UUID utilizando el keyVault.deleteKey() método de la siguiente manera:
keyVault = db.getKeyVault() keyVault.deleteKey(UUID("<UUID String>"))
Para obtener más información sobre las colecciones de Key Vault, consulte Claves de cifrado y Bóvedas de claves.
Obtén más información
Para obtener tutoriales que detallan cómo configurar una aplicación habilitada para CSFLE con cada uno de los proveedores de KMS compatibles, consulte las siguientes páginas:
Utilice el cifrado automático a nivel de campo del lado del cliente con AWS
Utilice el cifrado automático a nivel de campo del lado del cliente con Azure
Usa el cifrado a nivel de campo de lado del cliente automático con GCP
Utiliza el cifrado automático en el lado del cliente a nivel de campo con KMIP
Para ver ejemplos adicionales de esquemas de cifrado, consulta Esquemas de cifrado CSFLE.