Docs Menu
Docs Home
/ /
/ / /

Cifrado explícito de CSFLE

Aprenda a utilizar el mecanismo de cifrado explícito de cifrado a nivel de campo del lado del cliente (CSFLE).

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

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

  • Servidor comunitario MongoDB

  • MongoDB Enterprise Advanced

  • MongoDB Atlas

Para utilizar el cifrado explícito, debe realizar las siguientes acciones en su 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 OperacionesKMS involucradas en cifrado explícito.

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

  • Una instancia MongoClient con acceso a su colección de Key Vault

  • El espacio de nombres de su colección de Key Vault

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

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

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

Debe actualizar las operaciones de lectura y escritura en toda su aplicación de modo que ésta encripte los campos antes de realizar operaciones de lectura y escritura.

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

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

Puede descifrar sus campos cifrados de forma manual o automática cuando utilice 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 utilizar el decrypt método, 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 Key Vault

  • Especifique un objeto kmsProviders

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

Nota

El descifrado automático está disponible en el servidor comunitario MongoDB

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

  • Servidor comunitario MongoDB

  • MongoDB Enterprise Advanced

  • MongoDB Atlas

Para ver un fragmento de código que demuestra cómo habilitar el descifrado automático, seleccione la pestaña correspondiente a su idioma 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 desea insertar documentos con la siguiente estructura en su instancia de MongoDB:

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

En este ejemplo, utiliza la misma instancia MongoClient para acceder a su colección de Key Vault y para leer y escribir 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

Opciones de códec

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

Desea 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

Azar

Arreglo

Los siguientes fragmentos de código muestran cómo cifrar manualmente los campos de su documento e insertarlo en MongoDB:

Nota

La dataKeyId variable en los siguientes ejemplos se refiere a una clave de cifrado de datos (DEK). Para saber cómo generar una DEK con su proveedor de claves local, consulte la Guía de inicio rápido. Para saber cómo crear una DEK con un sistema de gestión de claves específico, consulte los 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 dataKeyId variable en los siguientes ejemplos se refiere a una clave de cifrado de datos (DEK). Para saber cómo generar una DEK con su proveedor de claves local, consulte la Guía de inicio rápido. Para saber cómo crear una DEK con un sistema de gestión de claves específico, consulte los 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 dataKeyId variable en los siguientes ejemplos se refiere a una clave de cifrado de datos (DEK). Para saber cómo generar una DEK con su proveedor de claves local, consulte la Guía de inicio rápido. Para saber cómo crear una DEK con un sistema de gestión de claves específico, consulte los 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 dataKeyId variable en los siguientes ejemplos se refiere a una clave de cifrado de datos (DEK). Para saber cómo generar una DEK con su proveedor de claves local, consulte la Guía de inicio rápido. Para saber cómo crear una DEK con un sistema de gestión de claves específico, consulte los 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 dataKeyId variable en los siguientes ejemplos se refiere a una clave de cifrado de datos (DEK). Para saber cómo generar una DEK con su proveedor de claves local, consulte la Guía de inicio rápido. Para saber cómo crear una DEK con un sistema de gestión de claves específico, consulte los 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 data_key_id variable en los siguientes ejemplos se refiere a una clave de cifrado de datos (DEK). Para saber cómo generar una DEK con su proveedor de claves local, consulte la Guía de inicio rápido. Para saber cómo crear una DEK con un sistema de gestión de claves específico, consulte los 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 realiza 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 como se especifica en la instancia de MongoDB.

Para saber cómo configurar la aplicación de CSFLE del lado del servidor, consulte Aplicación de esquemas del lado del servidor CSFLE.

Para obtener más información sobre las colecciones de Key Vault, las claves de cifrado de datos y las claves maestras de cliente, consulte Claves y bóvedas de claves.

Para obtener más información sobre los proveedores de KMS y los kmsProviders objetos, consulte Proveedores de KMS de CSFLE.

Volver

cifrado automático

En esta página