Join us at MongoDB.local London on 7 May to unlock new possibilities for your data. Use WEB50 to save 50%.
Register now >
Docs Menu
Docs Home
/ /
/ / /

Cifrado explícito de CSFLE

Aprende cómo utilizar el mecanismo de cifrado explícito de Cifrado a Nivel de Campo en el Lado del Cliente (CSFLE).

El cifrado explícito es un mecanismo en el que se especifica cómo cifrar y descifrar campos en el documento para cada operación que se realiza en la base de datos.

El cifrado explícito está disponible en los siguientes productos MongoDB de la versión 4.2 o posteriores:

  • MongoDB Community Server

  • MongoDB Enterprise Advanced

  • MongoDB Atlas

Para utilizar cifrado explícito, debes realizar las siguientes acciones en tu aplicación habilitada para CSFLE:

  • Crear una instancia de ClientEncryption

  • Cifrar campos en operaciones de lectura y escritura

  • Descifrar campos deforma manual o automática en sus documentos

Para utilizar el cifrado explícito, debe crear un ClientEncryption instancia. ClientEncryption es una abstracción utilizada en todos los controladores y mongosh que encapsula la colección Key Vault y KMS operaciones involucradas en el cifrado explícito.

Para crear una instancia ClientEncryption, debe especificar la siguiente información:

  • Una MongoClient instancia con acceso a tu Colección de Bóvedas de Llaves

  • El espacio de nombres de tu Colección de Bóvedas de Llaves

  • Un kmsProviders objeto configurado con acceso al proveedor KMS que aloja su clave maestra de cliente

Para obtener más ClientEncryption opciones, consulte opciones específicas de CSFLE MongoClient.

Para ver fragmentos de código que muestran cómo crear una instancia de ClientEncryption, consulta la sección Ejemplo de esta guía.

Debe actualizar las operaciones de lectura y guardado en toda su aplicación para que esta cifre los campos antes de realizar operaciones de lectura y guardado.

Para cifrar campos, utilice el método encrypt de su instancia ClientEncryption.

Para ver fragmentos de código que muestran cómo usar el método encrypt, consulte la sección Ejemplo de esta guía.

Puedes desencriptar tus campos cifrados de forma manual o automática cuando usas cifrado explícito.

Para descifrar manualmente tus campos, utiliza el método decrypt de tu instancia ClientEncryption.

Para ver fragmentos de código que muestran cómo usar el método decrypt, consulte la sección Ejemplo de esta guía.

Para descifrar los campos automáticamente, configurar la instancia de MongoClient de la siguiente manera:

  • Especifique su Colección de Bóvedas de Llaves

  • Especifica un objeto kmsProviders

  • Si utiliza MongoDB Community Server, configure la opción bypassAutoEncryption en True

Nota

El descifrado automático está disponible en MongoDB Community Server

Aunque el cifrado automático requiere MongoDB Enterprise o MongoDB Atlas, el descifrado automático está disponible en los siguientes productos de MongoDB:

  • MongoDB Community Server

  • MongoDB Enterprise Advanced

  • MongoDB Atlas

Para ver un snippet de código que demuestre cómo activar el descifrado automático, selecciona la pestaña correspondiente a tu lenguaje preferido:

var autoEncryptionOpts = {
keyVaultNamespace: keyVaultNamespace,
kmsProviders: kmsProviders,
bypassAutoEncryption: true,
};
var encryptedClient = Mongo(
connectionString,
autoEncryptionOpts
);
var clientSettings = MongoClientSettings.FromConnectionString(connectionString);
var autoEncryptionOptions = new AutoEncryptionOptions(
keyVaultNamespace: keyVaultNamespace,
kmsProviders: kmsProviders,
bypassAutoEncryption: true);
clientSettings.AutoEncryptionOptions = autoEncryptionOptions;
var client = new MongoClient(clientSettings);
autoEncryptionOpts := options.AutoEncryption().
SetKmsProviders(kmsProviders).
SetKeyVaultNamespace(KeyVaultNamespace).
SetBypassAutoEncryption(true)
client, err := mongo.Connect(context.TODO(), options.Client().ApplyURI(URI).SetAutoEncryptionOptions(autoEncryptionOpts))
if err != nil {
return fmt.Errorf("Connect error for encrypted client: %v", err)
}
defer func() {
_ = client.Disconnect(context.TODO())
}()
MongoClientSettings clientSettings = MongoClientSettings.builder()
.applyConnectionString(new ConnectionString(connectionString))
.autoEncryptionSettings(AutoEncryptionSettings.builder()
.keyVaultNamespace(keyVaultNamespace)
.kmsProviders(kmsProviders).bypassAutoEncryption(true)
.build())
.build();
MongoClient mongoClient = MongoClients.create(clientSettings);
const client = new MongoClient(connectionString, {
monitorCommands: true,
autoEncryption: {
keyVaultNamespace,
kmsProviders,
bypassAutoEncryption: true,
},
});
auto_encryption_opts = AutoEncryptionOpts(
kms_providers=kms_providers,
key_vault_namespace=key_vault_namespace,
bypass_auto_encryption=True,
)
client = MongoClient(auto_encryption_opts=auto_encryption_opts)

Supongamos que deseas insertar documentos con la siguiente estructura en tu instancia de MongoDB:

{
"name": "<name of person>",
"age": <age of person>,
"favorite-foods": ["<array of foods>"]
}
1

En este ejemplo, utilizas la misma instancia de MongoClient para acceder a tu Colección de Bóvedas de Llaves y para leer y guardar datos cifrados.

Los siguientes fragmentos de código muestran cómo crear una instancia MongoClient:

const autoEncryptionOpts = {
keyVaultNamespace: keyVaultNamespace,
kmsProviders: kmsProviders,
};
const encryptedClient = Mongo(connectionString, autoEncryptionOpts);
var client = new MongoClient(connectionString);
client, err := mongo.Connect(context.TODO(), options.Client().ApplyURI(URI))
if err != nil {
panic(fmt.Errorf("Client connect error %v", err))
}
MongoClient client = MongoClients.create(connectionString);
const client = new MongoClient(connectionString);
client = MongoClient(your_connection_uri)
2

Los siguientes fragmentos de código muestran cómo crear una instancia ClientEncryption:

const clientEncryption = encryptedClient.getClientEncryption();
var collection = client.GetDatabase(db).GetCollection<BsonDocument>(coll);
var clientEncryptionOptions = new ClientEncryptionOptions(
keyVaultClient: client,
keyVaultNamespace: keyVaultNamespace,
kmsProviders: kmsProviders);
var clientEncryption = new ClientEncryption(clientEncryptionOptions);
coll := client.Database(DbName).Collection(CollName)
clientEncryptionOpts := options.ClientEncryption().SetKeyVaultNamespace(KeyVaultNamespace).SetKmsProviders(kmsProviders)
clientEnc, err := mongo.NewClientEncryption(client, clientEncryptionOpts)
if err != nil {
panic(fmt.Errorf("NewClientEncryption error %v", err))
}
defer func() {
_ = clientEnc.Close(context.TODO())
}()
MongoCollection<Document> collection = client.getDatabase(db).getCollection(coll);
ClientEncryptionSettings clientEncryptionSettings = ClientEncryptionSettings.builder()
.keyVaultMongoClientSettings(MongoClientSettings.builder()
.applyConnectionString(new ConnectionString(connectionString))
.build())
.keyVaultNamespace(keyVaultNamespace)
.kmsProviders(kmsProviders)
.build();
ClientEncryption clientEncryption = ClientEncryptions.create(clientEncryptionSettings);
const collection = client.db(db).collection(coll);
const encryption = new ClientEncryption(client, {
keyVaultNamespace,
kmsProviders,
});
coll = client.employees.foods
client_encryption = ClientEncryption(
kms_providers,
"encryption.___keyVault",
client,
coll.codec_options,
)

Nota

CodecOptions

El controlador Python de MongoDB requiere que especifique el CodecOptions con el que desea cifrar y descifrar sus documentos.

Especifique el CodecOptions que ha configurado en el MongoClient, Database o Collection con el que está escribiendo datos de aplicación cifrados y descifrados en MongoDB.

3

Quieren cifrar los campos de su documento utilizando los siguientes algoritmos:

Nombre de campo
Algoritmo de cifrado
Tipo de campo BSON

name

Determinista

String

age

Sin cifrado

Int

favorite-foods

Aleatorio

Arreglo

Los siguientes snippets de código muestran cómo cifrar manualmente los campos de tu documento e insertar tu documento en MongoDB:

Nota

La variable dataKeyId en los siguientes ejemplos se refiere a una llave de cifrado de datos (DEK). Para aprender a generar un DEK con su proveedor de llaves local, consulte la Guía de inicio rápido. Para saber cómo crear un DEK con un sistema de gestión de claves específico, consulta Tutoriales de CSFLE.

const encName = clientEncryption.encrypt(
dataKeyId,
"Greg",
"AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
);
const encFoods = clientEncryption.encrypt(
dataKeyId,
["Cheese", "Grapes"],
"AEAD_AES_256_CBC_HMAC_SHA_512-Random"
);
db.getSiblingDB(database).getCollection(collection).insertOne({
name: encName,
foods: encFoods,
});

Nota

La variable dataKeyId en los siguientes ejemplos se refiere a una llave de cifrado de datos (DEK). Para aprender a generar un DEK con su proveedor de llaves local, consulte la Guía de inicio rápido. Para saber cómo crear un DEK con un sistema de gestión de claves específico, consulta Tutoriales de CSFLE.

var encryptedName = clientEncryption.Encrypt(
"Greg",
new EncryptOptions(algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic", keyId: dataKeyId),
CancellationToken.None);
var encryptedFoods = clientEncryption.Encrypt(
new BsonArray { "Cheese", "Grapes" },
new EncryptOptions(algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Random", keyId: dataKeyId),
CancellationToken.None);
collection.InsertOne(new BsonDocument { { "name", encryptedName }, { "age", 83 }, { "foods", encryptedFoods } });

Nota

La variable dataKeyId en los siguientes ejemplos se refiere a una llave de cifrado de datos (DEK). Para aprender a generar un DEK con su proveedor de llaves local, consulte la Guía de inicio rápido. Para saber cómo crear un DEK con un sistema de gestión de claves específico, consulta Tutoriales de CSFLE.

nameRawValueType, nameRawValueData, err := bson.MarshalValue("Greg")
if err != nil {
panic(err)
}
nameRawValue := bson.RawValue{Type: nameRawValueType, Value: nameRawValueData}
nameEncryptionOpts := options.Encrypt().
SetAlgorithm("AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic").
SetKeyID(dataKeyId)
nameEncryptedField, err := clientEnc.Encrypt(
context.TODO(),
nameRawValue,
nameEncryptionOpts)
if err != nil {
panic(err)
}
foodsRawValueType, foodsRawValueData, err := bson.MarshalValue(bson.A{"Grapes", "Cheese"})
if err != nil {
panic(err)
}
foodsRawValue := bson.RawValue{Type: foodsRawValueType, Value: foodsRawValueData}
encryptionOpts := options.Encrypt().
SetAlgorithm("AEAD_AES_256_CBC_HMAC_SHA_512-Random").
SetKeyID(dataKeyId)
foodsEncryptedField, err := clientEnc.Encrypt(
context.TODO(),
foodsRawValue,
encryptionOpts)
if err != nil {
panic(err)
}
_, err = coll.InsertOne(
context.TODO(),
bson.D{{"name", nameEncryptedField}, {"foods", foodsEncryptedField}, {"age", 83}})
if err != nil {
panic(err)
}

Nota

La variable dataKeyId en los siguientes ejemplos se refiere a una llave de cifrado de datos (DEK). Para aprender a generar un DEK con su proveedor de llaves local, consulte la Guía de inicio rápido. Para saber cómo crear un DEK con un sistema de gestión de claves específico, consulta Tutoriales de CSFLE.

BsonBinary encryptedName = clientEncryption.encrypt(new BsonString("Greg"), new EncryptOptions("AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic").keyId(dataKeyId));
BsonBinary encryptedFoods = clientEncryption.encrypt(new BsonArray().parse("[\"Grapes\", \"Foods\"]"), new EncryptOptions("AEAD_AES_256_CBC_HMAC_SHA_512-Random").keyId(dataKeyId));
collection.insertOne(new Document("name", encryptedName).append("foods", encryptedFoods).append("age", 83));

Nota

La variable dataKeyId en los siguientes ejemplos se refiere a una llave de cifrado de datos (DEK). Para aprender a generar un DEK con su proveedor de llaves local, consulte la Guía de inicio rápido. Para saber cómo crear un DEK con un sistema de gestión de claves específico, consulta Tutoriales de CSFLE.

encryptedName = await encryption.encrypt("Greg", {
algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
keyId: dataKeyId,
});
encryptedFoods = await encryption.encrypt(["Cheese", "Grapes"], {
algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
keyId: dataKeyId,
});
await collection.insertOne({
name: encryptedName,
age: 83,
foods: encryptedFoods,
});

Nota

La variable data_key_id en los siguientes ejemplos se refiere a una llave de cifrado de datos (DEK). Para aprender a generar un DEK con su proveedor de llaves local, consulte la Guía de inicio rápido. Para saber cómo crear un DEK con un sistema de gestión de claves específico, consulta Tutoriales de CSFLE.

encrypted_name = client_encryption.encrypt(
"Greg",
Algorithm.AEAD_AES_256_CBC_HMAC_SHA_512_Deterministic,
key_id=data_key_id,
)
encrypted_foods = client_encryption.encrypt(
["Cheese", "Grapes"],
Algorithm.AEAD_AES_256_CBC_HMAC_SHA_512_Random,
key_id=data_key_id,
)
coll.insert_one({"name": encrypted_name, "age": 83, "foods": encrypted_foods})
4

Los siguientes fragmentos de código muestran cómo recuperar el documento insertado y descifrar manualmente los campos cifrados:

const encNameQuery = clientEncryption.encrypt(
dataKeyId,
"Greg",
"AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
);
let doc = db.getSiblingDB(database).getCollection(collection).findOne({
name: encNameQuery,
});
console.log(doc);
doc.name = clientEncryption.decrypt(doc.name);
doc.foods = clientEncryption.decrypt(doc.foods);
console.log(doc);
var nameToQuery = "Greg";
var encryptedNameToQuery = clientEncryption.Encrypt(
nameToQuery,
new EncryptOptions(algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic", keyId: dataKeyId),
CancellationToken.None);
var doc = collection.Find(new BsonDocument { { "name", encryptedNameToQuery } }).Single();
Console.WriteLine($"Encrypted document: {doc}");
doc["name"] = clientEncryption.Decrypt(doc["name"].AsBsonBinaryData, CancellationToken.None);
doc["foods"] = clientEncryption.Decrypt(doc["foods"].AsBsonBinaryData, CancellationToken.None);
Console.WriteLine($"Decrypted field: {doc}");
nameQueryRawValueType, nameQueryRawValueData, err := bson.MarshalValue("Greg")
if err != nil {
panic(err)
}
nameQueryRawValue := bson.RawValue{Type: nameQueryRawValueType, Value: nameQueryRawValueData}
nameQueryEncryptionOpts := options.Encrypt().
SetAlgorithm("AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic").
SetKeyID(dataKeyId)
nameQueryEncryptedField, err := clientEnc.Encrypt(
context.TODO(),
nameQueryRawValue,
nameQueryEncryptionOpts)
if err != nil {
panic(err)
}
var result bson.M
err = coll.FindOne(
context.TODO(),
bson.D{{"name", nameQueryEncryptedField}}).Decode(&result)
if err != nil {
if err == mongo.ErrNoDocuments {
return
}
panic(err)
}
fmt.Printf("Encrypted Document: %s\n", result)
nameDecrypted, err := clientEnc.Decrypt(
context.TODO(),
result["name"].(primitive.Binary))
foodsDecrypted, err := clientEnc.Decrypt(
context.TODO(),
result["foods"].(primitive.Binary))
result["foods"] = foodsDecrypted
result["name"] = nameDecrypted
fmt.Printf("Decrypted Document: %s\n", result)
BsonBinary encryptedNameQuery = clientEncryption.encrypt(new BsonString("Greg"), new EncryptOptions("AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic").keyId(dataKeyId));
Document result = collection.find(eq("name", encryptedNameQuery)).first();
System.out.println("Encrypted Document: " + result.toJson());
result.replace("name", clientEncryption.decrypt(new BsonBinary(result.get("name", Binary.class).getData())));
result.replace("foods", clientEncryption.decrypt(new BsonBinary(result.get("foods", Binary.class).getData())));
System.out.println("Decrypted Document: " + result.toJson());
queryEncryptedName = await encryption.encrypt("Greg", {
algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
keyId: dataKeyId,
});
let doc = await collection.findOne({ name: queryEncryptedName });
console.log("Encrypted Document: ", doc);
doc.name = encryption.decrypt(doc.name);
doc.foods = encryption.decrypt(doc.foods);
console.log("Decrypted document: ", doc);
name_to_query = "Greg"
encrypted_name_to_query = client_encryption.encrypt(
name_to_query,
Algorithm.AEAD_AES_256_CBC_HMAC_SHA_512_Deterministic,
key_id=data_key_id,
)
doc = client.employees.foods.find_one({"name": encrypted_name_to_query})
print("Encrypted document: %s" % (doc,))
doc["name"] = client_encryption.decrypt(doc["name"])
doc["foods"] = client_encryption.decrypt(doc["foods"])
print("Decrypted document: %s" % (doc,))

MongoDB admite el uso de la validación de esquema para aplicar el cifrado de campos específicos en una colección.

Un cliente que realice cifrado a nivel de campo del lado del cliente con el mecanismo de cifrado explícito en una instancia de MongoDB configurada para aplicar el cifrado de ciertos campos debe cifrar esos campos según lo especificado en la instancia de MongoDB.

Para aprender a configurar la aplicación de CSFLE del lado del servidor, consulta Aplicación del esquema del lado del servidor CSFLE.

Para obtener más información sobre las Colecciones de Bóvedas de Llaves, las llaves de cifrado de datos y las llaves maestras de cliente, consulta Claves y Key Vaults.

Para obtener más información sobre KMS proveedores y kmsProviders objetos, consulta CSFLE KMS Providers.

Volver

cifrado automático

En esta página