Para agentes de IA: hay un índice de documentación disponible en https://www.mongodb.com/es/docs/llms.txt — versiones en markdown de todas las páginas están disponibles agregando .md a cualquier ruta URL.
Docs Menu

Configurar el cifrado consultable

En esta guía, aprenderá cómo usar el proveedor de EF Core para cifrar campos específicos de documentos mediante el cifrado consultable (QE).

El cifrado consultable encripta los campos confidenciales de los documentos en la capa de aplicación antes de escribir los datos en MongoDB, permitiendo a la vez que la aplicación consulte dichos campos. Solo las aplicaciones que tengan acceso a las claves de cifrado pueden leer los datos en texto plano. Si un atacante accede a la base de datos, solo podrá ver el texto cifrado, ya que carece de acceso a las claves de cifrado.

Por ejemplo, puede utilizar el cifrado consultable para cifrar campos que contengan:

  • Números de Seguro Social

  • Números de tarjetas de crédito

  • Información sobre salud o medicina

  • Información financiera

  • Cualquier otra información sensible o que permita identificar personalmente a una persona.

El proveedor de EF Core admite el cifrado consultable mediante una API de modelo fluida. Se configuran las propiedades de la entidad que se van a cifrar mediante el método OnModelCreating(), y el proveedor gestiona el cifrado automáticamente al leer y escribir datos.

Antes de configurar el cifrado consultable con el proveedor de EF Core, asegúrese de tener lo siguiente:

  • Un clúster de MongoDB Enterprise o MongoDB Atlas que ejecute MongoDB 7.0 o posterior.

  • Acceso a un Servicio de Gestión de Claves (KMS). Los proveedores de KMS compatibles incluyen Amazon Web Services, Azure, Google Cloud Platform, el Protocolo de Interoperabilidad de Gestión de Claves (KMIP) y proveedores de claves locales.

  • La biblioteca compartida de cifrado automáticoCRYPT_SHARED () o mongocryptd está instalada en su entorno. Para obtener información sobre cómo instalar la biblioteca compartida, consulte la sección «Instalar un componente de análisis de consultas» en la documentación del servidor MongoDB.

Las siguientes secciones describen cómo configurar las opciones de cifrado en su contexto y marcar las propiedades de la entidad para su cifrado en su modelo:

Antes de configurar cualquier contexto que utilice el cifrado consultable, debe registrar el proveedor de cifrado automático una sola vez para su aplicación ejecutando el siguiente código:

MongoClientSettings.Extensions.AddAutoEncryption();

Luego, crea una instancia MongoOptionsExtension y encadena los siguientes métodos antes de pasar la instancia al método UseMongoDB():

  • WithKmsProviders() — especifica su proveedor de KMS y sus credenciales.

  • WithKeyVaultNamespace() — especifica la colección utilizada para almacenar las claves de cifrado de datos.

  • WithCryptProvider() — especifica la biblioteca de cifrado que se va a utilizar y su ruta.

El siguiente ejemplo configura un proveedor KMS local para su uso en desarrollo:

var kmsProviders = new Dictionary<
string, IReadOnlyDictionary<string, object>>
{
{
"local",
new Dictionary<string, object>
{
{ "key", localMasterKey }
}
}
};
var keyVaultNamespace = CollectionNamespace.FromFullName(
"encryption.__keyVault");
var mongoOptions = new MongoOptionsExtension()
.WithConnectionString(connectionString)
.WithDatabaseName("myDatabase")
.WithKmsProviders(kmsProviders)
.WithKeyVaultNamespace(keyVaultNamespace)
.WithCryptProvider(
CryptProvider.AutoEncryptSharedLibrary,
Environment.GetEnvironmentVariable("CRYPT_SHARED_LIB_PATH"));
var optionsBuilder = new DbContextOptionsBuilder<MyDbContext>()
.UseMongoDB(mongoOptions);

Para usar mongocryptd en lugar de la biblioteca compartida, pase CryptProvider.Mongocryptd y la ruta al binario mongocryptd al método WithCryptProvider().

Advertencia

No utilice un proveedor de KMS local en producción. Sin un KMS remoto, corre el riesgo de sufrir accesos no autorizados a la clave maestra o la pérdida permanente de la clave necesaria para descifrar sus datos.

En el método OnModelCreating(), llama a un método de cifrado en cada propiedad que quieras cifrar. El método que elijas controla qué tipos de consulta están disponibles en ese campo:

Método
Soporte para consultas
notas

IsEncrypted(dataKeyId)

Ninguno

Cifra el campo sin soporte para consultas. Úselo para campos que almacena pero que nunca filtra directamente.

IsEncryptedForEquality(dataKeyId)

Igualdad (==)

No disponible para los tipos de almacenamiento BSON Decimal128, Double, Document o Array.

IsEncryptedForRange(min, max, dataKeyId)

Rango (>, <, >=, <=)

Solo compatible con los tipos de almacenamiento BSON DateTime, Decimal128, Double, Int32 y Int64.

Para cifrar una entidad de propiedad en lugar de una propiedad escalar, llame a IsEncrypted(dataKeyId) en el OwnedNavigationBuilder o OwnershipBuilder devuelto por OwnsOne() o OwnsMany().

Para ver un ejemplo completo que utiliza los métodos anteriores, consulte la sección Ejemplo: Cifrado de datos del paciente.

La siguiente entidad Patient define el modelo del documento, con los campos SSN y DateOfBirth a cifrar:

public class Patient
{
public ObjectId Id { get; set; }
public string Name { get; set; } = null!;
public string SSN { get; set; } = null!;
public DateTime DateOfBirth { get; set; }
}

El siguiente HospitalContext marca los campos que se cifrarán en el método OnModelCreating(). SSN se cifra sin soporte para consultas, y DateOfBirth se cifra con soporte para consultas de rango. El constructor acepta los ID de dos claves de cifrado de datos, que se crean en el almacén de claves antes de inicializar el contexto:

public class HospitalContext : DbContext
{
public DbSet<Patient> Patients { get; set; } = null!;
private readonly Guid _ssnDataKeyId;
private readonly Guid _dobDataKeyId;
public HospitalContext(
DbContextOptions options,
Guid ssnDataKeyId,
Guid dobDataKeyId)
: base(options)
{
_ssnDataKeyId = ssnDataKeyId;
_dobDataKeyId = dobDataKeyId;
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Patient>(entity =>
{
entity.ToCollection("patients");
entity.Property(p => p.SSN)
.IsEncrypted(_ssnDataKeyId);
entity.Property(p => p.DateOfBirth)
.IsEncryptedForRange(
new DateTime(1900, 1, 1),
new DateTime(2100, 12, 31),
_dobDataKeyId);
});
}
}

El siguiente código configura las opciones de cifrado, instancia el HospitalContext con los ID de clave de datos e inserta y consulta un documento Patient:

var mongoOptions = new MongoOptionsExtension()
.WithConnectionString("<connection string URI>")
.WithDatabaseName("hospitalDb")
.WithKmsProviders(kmsProviders)
.WithKeyVaultNamespace(keyVaultNamespace)
.WithCryptProvider(
CryptProvider.AutoEncryptSharedLibrary,
Environment.GetEnvironmentVariable("CRYPT_SHARED_LIB_PATH"));
using var context = new HospitalContext(
new DbContextOptionsBuilder<HospitalContext>()
.UseMongoDB(mongoOptions)
.Options,
ssnDataKeyId,
dobDataKeyId);
context.Database.EnsureCreated();
context.Patients.Add(new Patient
{
Name = "John Doe",
SSN = "123-45-6789",
DateOfBirth = new DateTime(1985, 6, 15)
});
context.SaveChanges();
var results = context.Patients
.Where(p => p.DateOfBirth > new DateTime(1980, 1, 1))
.ToList();

De forma predeterminada, el proveedor de EF Core aplica la configuración de cifrado de campos solo al cliente. El cifrado exclusivo para el cliente es apropiado durante el desarrollo, cuando el esquema de cifrado aún puede estar en evolución.

Para implementaciones en producción, registre el esquema de cifrado en el servidor al crear la colección. Una vez que el servidor dispone del esquema, aplica el cifrado independientemente de la configuración del cliente, protegiendo contra escrituras accidentales en texto plano por parte de clientes mal configurados. Tras registrar el esquema en el servidor, no podrá modificar los campos cifrados sin recrear la colección.

Para crear una colección con un esquema del lado del servidor, pase el Model de su contexto al QueryableEncryptionSchemaGenerator.GenerateSchemas(). Luego, pase el resultado al método CreateCollection(), como se muestra en el siguiente ejemplo:

var encryptedSchemas =
QueryableEncryptionSchemaGenerator.GenerateSchemas(
context.Model);
using var client = new MongoClient(
"<connection string URI>");
var database = client.GetDatabase("hospitalDb");
foreach (var entityType in context.Model
.GetEntityTypes()
.Where(e => e.IsDocumentRoot()))
{
var collectionName = entityType.GetCollectionName();
if (encryptedSchemas.TryGetValue(
collectionName, out var schema))
{
database.CreateCollection(
collectionName,
new CreateCollectionOptions
{
EncryptedFields = schema
});
}
}
context.Database.EnsureCreated();

Una vez que la colección cifrada existe en el servidor, puede configurar nuevas instancias de contexto para que utilicen solo el esquema del servidor. Establezca QueryableEncryptionSchemaMode.Ignore en MongoOptionsExtension, como se muestra en el siguiente ejemplo:

var mongoOptions = new MongoOptionsExtension()
.WithConnectionString("<connection string URI>")
.WithDatabaseName("hospitalDb")
.WithKmsProviders(kmsProviders)
.WithKeyVaultNamespace(keyVaultNamespace)
.WithCryptProvider(
CryptProvider.AutoEncryptSharedLibrary,
Environment.GetEnvironmentVariable("CRYPT_SHARED_LIB_PATH"))
.WithQueryableEncryptionSchemaMode(
QueryableEncryptionSchemaMode.Ignore);

En el modo Ignore, cualquier configuración IsEncrypted en el método OnModelCreating() no tiene efecto sobre el cifrado. El esquema del servidor controla qué campos se cifran.

Para obtener más información sobre el cifrado consultable, consulte las secciones "Cifrado consultable" y "Casos de uso del cifrado consultable" en el manual del servidor MongoDB.

Para obtener información completa sobre la implementación, consulte la documentación de la API del proveedor de EF Core.