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 Queryable Encryption

En esta guía, puede aprender a usar el proveedor de EF Core para cifrar campos de documentos específicos mediante Queryable Encryption (QE).

Queryable Encryption cifra los campos de documentos confidenciales en la capa de aplicación antes de escribir datos en MongoDB, al tiempo que permite que la aplicación query esos campos. Solo las aplicaciones que tienen acceso a sus llaves de cifrado pueden leer los datos de texto sin formato. Si un atacante obtiene acceso a la base de datos, solo podrá ver el texto cifrado porque no tiene acceso a las llaves de cifrado.

Por ejemplo, puede utilizar Queryable Encryption para cifrar campos que contengan:

  • Números de Seguridad Social

  • Números de tarjetas de crédito

  • Información médica o de salud

  • Información financiera

  • Cualquier otra información sensible o de identificación personal

El proveedor de EF Core admite Queryable Encryption a través de una API de modelo fluido. Configura qué propiedades de entidad cifrar mediante el método OnModelCreating(), y el proveedor gestiona el cifrado automáticamente al leer y escribir datos.

Antes de configurar Queryable Encryption 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 KMS (Key Management Service). Los proveedores de KMS compatibles incluyen Amazon Web Services, Azure, Google Cloud Platform, el protocolo de interoperabilidad de gestión de claves (KMIP) y los proveedores de claves locales.

  • La librería de cifrado automático (CRYPT_SHARED) o mongocryptd instalada en su entorno. Para aprender a instalar la librería compartida, consulte Instalar un componente de análisis de query en la documentación de MongoDB Server.

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

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

MongoClientSettings.Extensions.AddAutoEncryption();

A continuación, cree una instancia de MongoOptionsExtension y encadene 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 llaves de cifrado de datos.

  • WithCryptProvider() — especifica la librería de cifrado que se utilizará y su ruta.

El siguiente ejemplo configura un proveedor de KMS local para uso de 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 librería 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 acceso no autorizado a la clave maestra o la pérdida permanente de la clave necesaria para descifrar sus datos.

En el método OnModelCreating(), llame a un método de cifrado en cada propiedad que desee cifrar. El método que elija controla qué tipos de query están disponibles en ese campo:

Método
Soporte de query
notas

IsEncrypted(dataKeyId)

Ninguno

Cifra el campo sin compatibilidad con query. Utilícelo para los campos que almacena, pero nunca filtra directamente.

IsEncryptedForEquality(dataKeyId)

Igualdad (==)

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

IsEncryptedForRange(min, max, dataKeyId)

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

Admitido solo para los tipos de almacenamiento BSON DateTime, Decimal128, Double, Int32 y Int64.

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

Para obtener un ejemplo completo que utilice los métodos anteriores, consulte la sección Ejemplo: Cifrar datos del paciente.

La siguiente entidad Patient define el modelo orientado a documentos, con los campos SSN y DateOfBirth para 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 esos campos para el cifrado en el método OnModelCreating(). SSN se cifra sin soporte de query, y DateOfBirth se cifra con soporte de query de rango. El constructor acepta los ID de dos llaves de cifrado de datos, que se crean en el almacén de llaves 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, crea una instancia de 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();

Por defecto, el proveedor de EF Core aplica la configuración de cifrado de campo solo al cliente. El cifrado solo para clientes es adecuado durante el desarrollo, cuando el esquema de cifrado aún puede estar evolucionando.

Para las implementaciones de producción, registre el esquema de cifrado en el servidor cuando cree la colección. Una vez que el servidor contiene el esquema, aplica el cifrado independientemente de la configuración del cliente, lo que protege contra escrituras de texto sin formato accidentales de clientes mal configurados. Después de registrar el esquema en el servidor, no puede cambiar qué campos se cifran sin volver a crear la colección.

Para crear una colección con un esquema del lado del servidor, pase el Model de su contexto a 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 exista en el servidor, puede configurar nuevas instancias de contexto para usar solo el esquema del servidor. Establezca QueryableEncryptionSchemaMode.Ignore en el 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 ningún efecto en el cifrado. El esquema del servidor controla qué campos están cifrados.

Para obtener más información sobre Queryable Encryption, vea las secciones Queryable Encryption y Casos de uso de Queryable Encryption en el manual de MongoDB Server.

Para obtener detalles completos de la implementación, consulte la documentación de la API del proveedor de EF Core.