Make the MongoDB docs better! We value your opinion. Share your feedback for a chance to win $100.
Click here >
Docs Menu
Docs Home
/ /
/ / /

Gestión de claves de encriptación

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

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 claves y bóvedas de claves, consulte Claves y Bóvedas de claves.

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 clave 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 aprender más sobre estos proveedores, incluyendo diagramas que muestran cómo tu aplicación los utiliza para realizar cifrado a nivel de campo del lado del cliente, consulta proveedores CSFLE KMS.

Usar un sistema remoto de gestión de claves para administrar tu Clave maestra de cliente (CMK) tiene las siguientes ventajas sobre el uso de tu sistema de archivos local para host 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 para clientes remotos

  • Copia de seguridad y recuperación automatizadas de claves

  • Gestión centralizada del ciclo de vida de las claves de cifrado

Además, para los siguientes proveedores de KMS, su KMS cifra y descifra de forma remota su clave de cifrado de datos, asegurándose de que su clave maestra de cliente nunca se exponga a su aplicación habilitada para CSFLE:

  • Amazon Web Services KMS

  • Azure Key Vault

  • Google Cloud KMS

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.

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 de KMS de CSFLE.

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.

Tienes que referirte a un nombre alternativo clave con un puntero JSON. Un puntero JSON es una string precedida por el carácter "/" que se puede usar para acceder a un valor de campo específico en el mismo documento o en otro. Utiliza punteros JSON para hacer referencia a un campo en tu query o actualizar el documento que contiene el valor del nombre alternativo de tu 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.

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.

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.

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.

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 Key Vault, consulte Colecciones de Key Vault.

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:

Para ver ejemplos adicionales de esquemas de cifrado, consulta Esquemas de cifrado CSFLE.

Volver

Schemas