En esta guía puedes aprender cómo gestionar tus claves de cifrado con un Sistema de Gestió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
Sistema de gestión de claves (KMS)
Para obtener más información sobre las claves y los almacenes de claves, consulte Claves de cifrado y bóvedas de claves.
Servicios de gestión de claves admitidos
El cifrado de nivel de campo del lado del cliente admite los siguientes proveedores de sistemas de gestió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 los diagramas que muestran cómo tu aplicación los utiliza para realizar el cifrado a nivel de campo del lado del cliente, consulta Proveedores 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.Asigna dinámicamente DEK en tiempo de ejecución.
Crea una llave de cifrado de datos con un nombre alternativo
Importante
Requisito previo
Antes de agregar un nuevo nombre alternativo de clave, debes 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 clave con un puntero JSON. Utilice punteros JSON para hacer referencia a un campo en su query o documento de actualizar que contenga el valor del nombre alternativo de su 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 campo salary está cifrado por la DEK que tiene el nombre alternativo my-alt-name.
Asignar claves dinámicamente en tiempo de ejecución
Puedes usar nombres de claves alternativos para establecer dinámicamente la llave de cifrado de datos para un campo en tiempo de ejecución. Utiliza esta funcionalidad para cifrar documentos individuales con diferentes 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 campo salary.encrypt.keyId contiene un puntero JSON al campo fieldWithAltName del documento insertado. Como resultado, los campos salary en los dos documentos de ejemplo se cifran cada uno mediante un DEK específico para el documento individual. 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, puedes rotar las claves de cifrado utilizando el método rewrapManyDataKey. El método rewrapManyDataKey desencripta automáticamente varias claves de datos y las vuelve a encriptar utilizando una llave maestra de cliente especificada. Luego, actualiza las claves rotadas en la Colección de Bóvedas de Llaves. Este método le permite rotar las llaves de cifrado basándose en dos argumentos opcionales:
Un filtro utilizado para especificar qué claves rotar. Si ninguna clave de datos coincide con el filtro dado, no se rotan claves. Omite el filtro para rotar todas las claves de tu Colección de Bóvedas de Llaves.
Un objeto que representa una nueva llave maestra de cliente. Omitir este objeto para rotar las claves de datos usando sus CMKs 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 objeto dataKeyOpts para su proveedor de KMS, consulte Servicios compatibles de gestión de claves.
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
La shell de MongoDB te permite borrar una DEK mediante UUID utilizando el método keyVault.deleteKey() de la siguiente manera:
keyVault = db.getKeyVault() keyVault.deleteKey(UUID("<UUID String>"))
Para obtener más información sobre las Colecciones de Bóvedas de Llaves, consulta llaves de cifrado y Key Vaults.
Obtén más información
Para tutoriales detallados sobre cómo configurar una aplicación habilitada para CSFLE con cada uno de los proveedores compatibles de KMS, consulte las siguientes páginas:
Utiliza el cifrado automático de nivel de campo del lado del cliente con AWS
Utiliza el cifrado automático de 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.