En esta guía, puede aprender a administrar sus claves de cifrado con un sistema de administración de claves (KMS) en su aplicación habilitada para cifrado de nivel de campo del lado del cliente (CSFLE).
Componentes de cifrado
MongoDB utiliza los siguientes componentes para realizar el cifrado del lado del cliente a nivel de campo:
Claves de cifrado de datos (DEK)
Llaves maestras del 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 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 (solo para pruebas)
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 su aplicación los utiliza para realizar el cifrado a nivel de campo del lado del cliente, consulte Proveedores CSFLE KMS.
Razones para utilizar un sistema de gestión remota de claves
El uso de un sistema de administración de claves remoto para administrar su clave maestra de cliente tiene las siguientes ventajas sobre el uso de su sistema de archivos local para alojar la CMK:
Almacenamiento seguro de la clave con auditoría de acceso
Reducción del riesgo de problemas de permisos de acceso
Disponibilidad y distribución de la clave a clientes remotos
Copia de seguridad y recuperación de claves automatizadas
Gestión centralizada del ciclo de vida de las claves de cifrado
Además, para los siguientes proveedores de KMS, su KMS encripta y desencripta de forma remota su clave de encriptación de datos, lo que garantiza que su clave maestra de cliente nunca quede expuesta a su aplicación habilitada para CSFLE:
Amazon Web Services KMS
Azure Key Vault
Google Cloud KMS
Administrar el nombre alternativo de una clave de cifrado de datos
Puede asignar nombres alternativos a una clave de cifrado de datos para facilitar su consulta. Asignar nombres alternativos le permite realizar las siguientes acciones:
Hacer referencia a un DEK por medios diferentes a los
_idcampo.Asignar DEK dinámicamente en tiempo de ejecución.
Crear una clave de cifrado de datos con un nombre alternativo
Importante
Requisito previo
Antes de agregar un nuevo nombre alternativo de clave, debe crear un índice único en el campo keyAltNames. El cifrado a nivel de campo del lado del cliente depende de la unicidad de los nombres alternativos de clave, impuesta por el servidor.
Para saber cómo crear un índice único, consulte Índices únicos.
El siguiente ejemplo crea una clave de cifrado de datos con un nombre alternativo. Seleccione la pestaña correspondiente al idioma de su controlador:
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 dataKeyOpts los kmsProviders objetos y,consulte Proveedores CSFLE KMS.
Utilice nombres alternativos de clave en un esquema de cifrado automático
Los esquemas de cifrado contienen reglas definidas por el usuario que identifican qué campos deben cifrarse y cómo hacerlo. En las reglas de cifrado, puede especificar nombres de clave alternativos para la clave de cifrado de datos que cifra el campo.
Debe hacer referencia a un nombre alternativo de clave con un puntero JSON. Un puntero JSON es una cadena con el prefijo "/" que permite acceder al valor de un campo específico en el mismo documento o en otro. Utilice punteros JSON para hacer referencia a un campo en su consulta o documento de actualización que contenga el valor de su 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 el campo de forma determinista, debe especificar el _id de la clave que desea usar para cifrar el 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 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" }
Inserte los documentos anteriores utilizando un cliente habilitado para CSFLE configurado con el esquema de cifrado del 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 claves de cifrado mediante 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 especificada. 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.
Eliminar una clave de cifrado de datos
Puede eliminar una clave de cifrado de datos de su colección de Key Vault mediante operaciones CRUD estándar. Si elimina una DEK, todos los campos cifrados con ella quedarán permanentemente ilegibles.
Tip
Característica 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 Colecciones de Key Vault.
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
Utilice el cifrado automático a nivel de campo del lado del cliente con GCP
Utilice el cifrado automático a nivel de campo del lado del cliente con KMIP
Para ver ejemplos adicionales de esquemas de cifrado, consulta Esquemas de cifrado CSFLE.