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
/ /

Inicio rápido CSFLE

Esta guía le muestra cómo cifrar un documento con cifrado de nivel de campo del lado del cliente (CSFLE) automático y un controlador MongoDB.

Después de completar esta guía, deberías tener los siguientes conocimientos y software:

  • Conocimiento de los pasos para configurar un controlador para cifrar campos en un documento.

  • Una aplicación cliente funcional, pero no apta para producción, que utiliza el automático de cifrado a nivel de campo del lado del cliente.

Importante

No utilice esta aplicación en producción

Dado que esta aplicación de ejemplo almacena una llave de cifrado en el sistema de archivos de tu aplicación, te arriesgas a un acceso no autorizado a la llave o a la pérdida de la llave para descifrar tus datos.

Para ver un tutorial que demuestre cómo crear una aplicación lista para producción habilitada para CSFLE, consulta Tutoriales de CSFLE.

Para completar y ejecutar el código de esta guía, debes configurar tu entorno de desarrollo como se muestra en la página Requisitos de instalación.

Seleccione el lenguaje de programación para el cual desea ver ejemplos de código de la Select your language menú desplegable en el lado derecho de la página.

Tip

Ver: Solicitud completa

Para ver el código completo de la aplicación ejecutable para este tutorial, vaya al siguiente enlace:

Aplicación de C# completa

// You are viewing the C# driver code examples.
// Use the dropdown menu to select a different driver.
// You are viewing the Golang driver code examples.
// Use the dropdown menu to select a different driver.

Importante

Al construir o ejecutar el código Go en esta guía utilizando go build o go run, siempre incluye la cse restricción de compilación para activar CSFLE. Consulte el siguiente comando de shell como ejemplo de inclusión de la restricción de compilación:

go run -tags cse insert-encrypted-document.go
// You are viewing the Java synchronous driver code examples.
// Use the dropdown menu to select a different driver.
// You are viewing the Node.js driver code examples.
// Use the dropdown menu to select a different driver.
# You are viewing the Python driver code examples.
# Use the dropdown menu to select a different driver.
1

Debes crear una llave maestra de cliente (CMK) para realizar CSFLE.

Cree una clave maestra de cliente de 96 bytes y guárdela en su proveedor de claves local, que es su sistema de archivos, como el master-key.txt archivo:

const fs = require("fs");
const crypto = require("crypto");
try {
fs.writeFileSync("master-key.txt", crypto.randomBytes(96));
} catch (err) {
console.error(err);
}
using (var randomNumberGenerator = System.Security.Cryptography.RandomNumberGenerator.Create())
{
var bytes = new byte[96];
randomNumberGenerator.GetBytes(bytes);
var localMasterKeyBase64Write = Convert.ToBase64String(bytes);
Console.WriteLine(localMasterKeyBase64Write);
File.WriteAllText("master-key.txt", localMasterKeyBase64Write);
}
func localMasterKey() []byte {
key := make([]byte, 96)
if _, err := rand.Read(key); err != nil {
log.Fatalf("Unable to create a random 96 byte data key: %v", err)
}
if err := ioutil.WriteFile("master-key.txt", key, 0644); err != nil {
log.Fatalf("Unable to write key to file: %v", err)
}
return key
}
byte[] localMasterKeyWrite = new byte[96];
new SecureRandom().nextBytes(localMasterKeyWrite);
try (FileOutputStream stream = new FileOutputStream("master-key.txt")) {
stream.write(localMasterKeyWrite);
}
import os
path = "master-key.txt"
file_bytes = os.urandom(96)
with open(path, "wb") as f:
f.write(file_bytes)

Advertencia

No utilizar el proveedor de clave local en producción

El proveedor de claves local es un método de almacenamiento inseguro y no se recomienda para producción. En su lugar, debe almacenar sus claves maestras de cliente en un sistema de gestión de claves (KMS) remoto.

Para aprender a usar un KMS remoto en tu implementación de CSFLE, consulta la guía Tutoriales de CSFLE.

Tip

Genera una llave maestra de cliente desde la línea de comandos

Utilice el siguiente comando para generar una CMK desde un shell de Unix o PowerShell:

  • Shell de Unix/macOS:

    echo $(head -c 96 /dev/urandom | base64 | tr -d '\n')
  • Potencia Shell:

    $r=[byte[]]::new(64);$g=[System.Security.Cryptography.RandomNumberGenerator]::Create();$g.GetBytes($r);[Convert]::ToBase64String($r)

Guarde la salida del comando anterior en un archivo llamado customer-master-key.txt.

Tip

Consultar: Código completo

Para ver el código completo para crear una llave maestra de cliente, consulte nuestro repositorio Github.

Para ver el código completo para crear una llave maestra de cliente, consulte nuestro repositorio Github.

Para ver el código completo para crear una llave maestra de cliente, consulte nuestro repositorio Github.

Para ver el código completo para crear una llave maestra de cliente, consulte nuestro repositorio Github.

Para ver el código completo para crear una llave maestra de cliente, consulte nuestro repositorio Github.

2

Crea un índice parcial único en el campo keyAltNames de tu namespace encryption.__keyVault. 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.

Seleccione la pestaña correspondiente al controlador MongoDB preferido:

var connectionString = "<Your MongoDB URI>";
var keyVaultNamespace = CollectionNamespace.FromFullName("encryption.__keyVault");
var keyVaultClient = new MongoClient(connectionString);
var indexOptions = new CreateIndexOptions<BsonDocument>();
indexOptions.Unique = true;
indexOptions.PartialFilterExpression = new BsonDocument { { "keyAltNames", new BsonDocument { { "$exists", new BsonBoolean(true) } } } };
var builder = Builders<BsonDocument>.IndexKeys;
var indexKeysDocument = builder.Ascending("keyAltNames");
var indexModel = new CreateIndexModel<BsonDocument>(indexKeysDocument, indexOptions);
var keyVaultDatabase = keyVaultClient.GetDatabase(keyVaultNamespace.DatabaseNamespace.ToString());
// Drop the Key Vault Collection in case you created this collection
// in a previous run of this application.
keyVaultDatabase.DropCollection(keyVaultNamespace.CollectionName);
// Drop the database storing your encrypted fields as all
// the DEKs encrypting those fields were deleted in the preceding line.
keyVaultClient.GetDatabase("medicalRecords").DropCollection("patients");
var keyVaultCollection = keyVaultDatabase.GetCollection<BsonDocument>(keyVaultNamespace.CollectionName.ToString());
keyVaultCollection.Indexes.CreateOne(indexModel);
uri := "<Your MongoDB URI>"
keyVaultClient, err := mongo.Connect(context.TODO(), options.Client().ApplyURI(uri))
if err != nil {
return fmt.Errorf("Connect error for regular client: %v", err)
}
defer func() {
_ = keyVaultClient.Disconnect(context.TODO())
}()
keyVaultColl := "__keyVault"
keyVaultDb := "encryption"
keyVaultNamespace := keyVaultDb + "." + keyVaultColl
keyVaultIndex := mongo.IndexModel{
Keys: bson.D{{"keyAltNames", 1}},
Options: options.Index().
SetUnique(true).
SetPartialFilterExpression(bson.D{
{"keyAltNames", bson.D{
{"$exists", true},
}},
}),
}
// Drop the Key Vault Collection in case you created this collection
// in a previous run of this application.
if err = keyVaultClient.Database(keyVaultDb).Collection(keyVaultColl).Drop(context.TODO()); err != nil {
log.Fatalf("Collection.Drop error: %v", err)
}
// Drop the database storing your encrypted fields as all
// the DEKs encrypting those fields were deleted in the preceding line.
if err = keyVaultClient.Database("medicalRecords").Collection("patients").Drop(context.TODO()); err != nil {
log.Fatalf("Collection.Drop error: %v", err)
}
_, err = keyVaultClient.Database(keyVaultDb).Collection(keyVaultColl).Indexes().CreateOne(context.TODO(), keyVaultIndex)
if err != nil {
panic(err)
}
String connectionString = "<Your MongoDB URI>";
String keyVaultDb = "encryption";
String keyVaultColl = "__keyVault";
String keyVaultNamespace = keyVaultDb + "." + keyVaultColl;
MongoClient keyVaultClient = MongoClients.create(connectionString);
// Drop the Key Vault Collection in case you created this collection
// in a previous run of this application.
keyVaultClient.getDatabase(keyVaultDb).getCollection(keyVaultColl).drop();
// Drop the database storing your encrypted fields as all
// the DEKs encrypting those fields were deleted in the preceding line.
keyVaultClient.getDatabase("medicalRecords").getCollection("patients").drop();
MongoCollection keyVaultCollection = keyVaultClient.getDatabase(keyVaultDb).getCollection(keyVaultColl);
IndexOptions indexOpts = new IndexOptions().partialFilterExpression(new BsonDocument("keyAltNames", new BsonDocument("$exists", new BsonBoolean(true) ))).unique(true);
keyVaultCollection.createIndex(new BsonDocument("keyAltNames", new BsonInt32(1)), indexOpts);
keyVaultClient.close();
const uri = "<Your Connection String>";
const keyVaultDatabase = "encryption";
const keyVaultCollection = "__keyVault";
const keyVaultNamespace = `${keyVaultDatabase}.${keyVaultCollection}`;
const keyVaultClient = new MongoClient(uri);
await keyVaultClient.connect();
const keyVaultDB = keyVaultClient.db(keyVaultDatabase);
// Drop the Key Vault Collection in case you created this collection
// in a previous run of this application.
await keyVaultDB.dropDatabase();
// Drop the database storing your encrypted fields as all
// the DEKs encrypting those fields were deleted in the preceding line.
await keyVaultClient.db("medicalRecords").dropDatabase();
const keyVaultColl = keyVaultDB.collection(keyVaultCollection);
await keyVaultColl.createIndex(
{ keyAltNames: 1 },
{
unique: true,
partialFilterExpression: { keyAltNames: { $exists: true } },
}
);
connection_string = "<your connection string here>"
key_vault_coll = "__keyVault"
key_vault_db = "encryption"
key_vault_namespace = f"{key_vault_db}.{key_vault_coll}"
key_vault_client = MongoClient(connection_string)
# Drop the Key Vault Collection in case you created this collection
# in a previous run of this application.
key_vault_client.drop_database(key_vault_db)
# Drop the database storing your encrypted fields as all
# the DEKs encrypting those fields were deleted in the preceding line.
key_vault_client["medicalRecords"].drop_collection("patients")
key_vault_client[key_vault_db][key_vault_coll].create_index(
[("keyAltNames", ASCENDING)],
unique=True,
partialFilterExpression={"keyAltNames": {"$exists": True}},
)
3
1

Recupere el contenido del archivo de clave maestra del cliente que generó en el paso Crear una clave maestra del cliente de esta guía.

Pase el valor de la CMK a la configuración de su proveedor de KMS. El cliente utiliza esta configuración para descubrir la CMK. Dado que utiliza el proveedor de claves local, configure el nombre del proveedor local como.

var kmsProviders = new Dictionary<string, IReadOnlyDictionary<string, object>>();
var provider = "local";
string localMasterKeyBase64Read = File.ReadAllText("master-key.txt");
var localMasterKeyBytes = Convert.FromBase64String(localMasterKeyBase64Read);
var localOptions = new Dictionary<string, object>
{
{ "key", localMasterKeyBytes }
};
kmsProviders.Add("local", localOptions);
key, err := ioutil.ReadFile("master-key.txt")
if err != nil {
log.Fatalf("Could not read the key from master-key.txt: %v", err)
}
provider := "local"
kmsProviders := map[string]map[string]interface{}{"local": {"key": key}}
String kmsProvider = "local";
String path = "master-key.txt";
byte[] localMasterKeyRead = new byte[96];
try (FileInputStream fis = new FileInputStream(path)) {
if (fis.read(localMasterKeyRead) < 96)
throw new Exception("Expected to read 96 bytes from file");
}
Map<String, Object> keyMap = new HashMap<String, Object>();
keyMap.put("key", localMasterKeyRead);
Map<String, Map<String, Object>> kmsProviders = new HashMap<String, Map<String, Object>>();
kmsProviders.put("local", keyMap);
const provider = "local";
const path = "./master-key.txt";
const localMasterKey = fs.readFileSync(path);
const kmsProviders = {
local: {
key: localMasterKey,
},
};
path = "./master-key.txt"
with open(path, "rb") as f:
local_master_key = f.read()
kms_providers = {
"local": {
"key": local_master_key # local_master_key variable from the previous step
},
}
2

Construya un cliente con su cadena de conexión de MongoDB y el namespace de la Colección de Bóvedas de Llaves, y cree una llave de cifrado de datos:

Nota

Permisos del espacio de nombres de la colección Key Vault

Para completar este tutorial, el usuario de base de datos que tu aplicación utiliza para conectar a MongoDB debe tener permisos dbAdmin en los siguientes espacios de nombres:

  • encryption.__keyVault

  • medicalRecords database

var clientEncryptionOptions = new ClientEncryptionOptions(
keyVaultClient: keyVaultClient,
keyVaultNamespace: keyVaultNamespace,
kmsProviders: kmsProviders
);
var clientEncryption = new ClientEncryption(clientEncryptionOptions);
var dataKeyOptions = new DataKeyOptions();
var dataKeyId = clientEncryption.CreateDataKey(provider, dataKeyOptions, CancellationToken.None);
var dataKeyIdBase64 = Convert.ToBase64String(GuidConverter.ToBytes(dataKeyId, GuidRepresentation.Standard));
Console.WriteLine($"DataKeyId [base64]: {dataKeyIdBase64}");
clientEncryptionOpts := options.ClientEncryption().SetKeyVaultNamespace(keyVaultNamespace).
SetKmsProviders(kmsProviders)
clientEnc, err := mongo.NewClientEncryption(keyVaultClient, clientEncryptionOpts)
if err != nil {
return fmt.Errorf("NewClientEncryption error %v", err)
}
defer func() {
_ = clientEnc.Close(context.TODO())
}()
dataKeyOpts := options.DataKey()
dataKeyID, err := clientEnc.CreateDataKey(context.TODO(), provider, dataKeyOpts)
if err != nil {
return fmt.Errorf("create data key error %v", err)
}
fmt.Printf("DataKeyId [base64]: %s\n", base64.StdEncoding.EncodeToString(dataKeyID.Data))
ClientEncryptionSettings clientEncryptionSettings = ClientEncryptionSettings.builder()
.keyVaultMongoClientSettings(MongoClientSettings.builder()
.applyConnectionString(new ConnectionString(connectionString))
.build())
.keyVaultNamespace(keyVaultNamespace)
.kmsProviders(kmsProviders)
.build();
MongoClient regularClient = MongoClients.create(connectionString);
ClientEncryption clientEncryption = ClientEncryptions.create(clientEncryptionSettings);
BsonBinary dataKeyId = clientEncryption.createDataKey(kmsProvider, new DataKeyOptions());
String base64DataKeyId = Base64.getEncoder().encodeToString(dataKeyId.getData());
System.out.println("DataKeyId [base64]: " + base64DataKeyId);
clientEncryption.close();
const client = new MongoClient(uri);
await client.connect();
const encryption = new ClientEncryption(client, {
keyVaultNamespace,
kmsProviders,
});
const key = await encryption.createDataKey(provider);
console.log("DataKeyId [base64]: ", key.toString("base64"));
await keyVaultClient.close();
await client.close();

Nota

Import ClientEncryption

Al utilizar el controlador de Node.js versión 6.0 y posteriores, se debe importar ClientEncryption desde mongodb.

Para versiones anteriores del controlador, importe ClientEncryption desde mongodb-client-encryption.

key_vault_database = "encryption"
key_vault_collection = "__keyVault"
key_vault_namespace = f"{key_vault_database}.{key_vault_collection}"
client = MongoClient(connection_string)
client_encryption = ClientEncryption(
kms_providers, # pass in the kms_providers variable from the previous step
key_vault_namespace,
client,
CodecOptions(uuid_representation=STANDARD),
)
data_key_id = client_encryption.create_data_key("local")
base_64_data_key_id = base64.b64encode(data_key_id)
print("DataKeyId [base64]: ", base_64_data_key_id)

La salida del código anterior debería parecerse a la siguiente:

DataKeyId [base64]: 3k13WkSZSLy7kwAAP4HDyQ==

Tip

Consultar: Código completo

Para ver el código completo para crear una clave de cifrado de datos, consulte nuestro repositorio de Github.

Para ver el código completo para crear una clave de cifrado de datos, consulte nuestro repositorio de Github.

Para ver el código completo para crear una clave de cifrado de datos, consulte nuestro repositorio de Github.

Para ver el código completo para crear una clave de cifrado de datos, consulte nuestro repositorio de Github.

Para ver el código completo para crear una clave de cifrado de datos, consulte nuestro repositorio de Github.

4
1

Especifica encryption.__keyVault como el namespace de la Colección de Bóvedas de Llaves.

var keyVaultNamespace = CollectionNamespace.FromFullName("encryption.__keyVault");
keyVaultNamespace := "encryption.__keyVault"
String keyVaultNamespace = "encryption.__keyVault";
const keyVaultNamespace = "encryption.__keyVault";
key_vault_namespace = "encryption.__keyVault"
2

Especifique el proveedor de KMS y especifique su clave en línea:

var kmsProviders = new Dictionary<string, IReadOnlyDictionary<string, object>>();
var provider = "local";
var localMasterKeyPath = "master-key.txt";
string localMasterKeyBase64Read = File.ReadAllText(localMasterKeyPath);
var localMasterKeyBytes = Convert.FromBase64String(localMasterKeyBase64Read);
var localOptions = new Dictionary<string, object>
{
{ "key", localMasterKeyBytes }
};
kmsProviders.Add(provider, localOptions);
key, err := ioutil.ReadFile("master-key.txt")
if err != nil {
log.Fatalf("Could not read the key from master-key.txt: %v", err)
}
kmsProviders := map[string]map[string]interface{}{"local": {"key": key}}
String kmsProvider = "local";
String path = "master-key.txt";
byte[] localMasterKeyRead = new byte[96];
try (FileInputStream fis = new FileInputStream(path)) {
if (fis.read(localMasterKeyRead) < 96)
throw new Exception("Expected to read 96 bytes from file");
}
Map<String, Object> keyMap = new HashMap<String, Object>();
keyMap.put("key", localMasterKeyRead);
Map<String, Map<String, Object>> kmsProviders = new HashMap<String, Map<String, Object>>();
kmsProviders.put("local", keyMap);
const fs = require("fs");
const provider = "local";
const path = "./master-key.txt";
const localMasterKey = fs.readFileSync(path);
const kmsProviders = {
local: {
key: localMasterKey,
},
};
path = "./master-key.txt"
with open(path, "rb") as f:
local_master_key = f.read()
kms_providers = {
"local": {
"key": local_master_key # local_master_key variable from the previous step
},
}
3

Tip

Agregue su clave de cifrado de datos Base64 ID

Asegúrate de actualizar el siguiente código para incluir tu ID Base64 DEK. Recibiste este valor en el paso Genera tu llave de cifrado de datos de esta guía.

var keyId = "<Your base64 DEK ID here>";
var schema = new BsonDocument
{
{ "bsonType", "object" },
{
"encryptMetadata",
new BsonDocument("keyId", new BsonArray(new[] { new BsonBinaryData(Convert.FromBase64String(keyId), BsonBinarySubType.UuidStandard) }))
},
{
"properties",
new BsonDocument
{
{
"ssn", new BsonDocument
{
{
"encrypt", new BsonDocument
{
{ "bsonType", "int" },
{ "algorithm", "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" }
}
}
}
},
{
"bloodType", new BsonDocument
{
{
"encrypt", new BsonDocument
{
{ "bsonType", "string" },
{ "algorithm", "AEAD_AES_256_CBC_HMAC_SHA_512-Random" }
}
}
}
},
{
"medicalRecords", new BsonDocument
{
{
"encrypt", new BsonDocument
{
{ "bsonType", "array" },
{ "algorithm", "AEAD_AES_256_CBC_HMAC_SHA_512-Random" }
}
}
}
},
{
"insurance", new BsonDocument
{
{ "bsonType", "object" },
{
"properties", new BsonDocument
{
{
"policyNumber", new BsonDocument
{
{
"encrypt", new BsonDocument
{
{ "bsonType", "int" },
{ "algorithm", "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" }
}
}
}
}
}
}
}
}
}
}
};
var schemaMap = new Dictionary<string, BsonDocument>();
schemaMap.Add(dbNamespace, schema);
dek_id := "<Your Base64 DEK ID>"
schema_template := `{
"bsonType": "object",
"encryptMetadata": {
"keyId": [
{
"$binary": {
"base64": "%s",
"subType": "04"
}
}
]
},
"properties": {
"insurance": {
"bsonType": "object",
"properties": {
"policyNumber": {
"encrypt": {
"bsonType": "int",
"algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
}
}
}
},
"medicalRecords": {
"encrypt": {
"bsonType": "array",
"algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
}
},
"bloodType": {
"encrypt": {
"bsonType": "string",
"algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
}
},
"ssn": {
"encrypt": {
"bsonType": "int",
"algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
}
}
}
}`
schema := fmt.Sprintf(schema_template, dek_id)
var schemaDoc bson.Raw
if err := bson.UnmarshalExtJSON([]byte(schema), true, &schemaDoc); err != nil {
return fmt.Errorf("UnmarshalExtJSON error: %v", err)
}
schemaMap := map[string]interface{}{
dbName + "." + collName: schemaDoc,
}
String dekId = "<paste-base-64-encoded-data-encryption-key-id>>";
Document jsonSchema = new Document().append("bsonType", "object").append("encryptMetadata",
new Document().append("keyId", new ArrayList<>((Arrays.asList(new Document().append("$binary", new Document()
.append("base64", dekId)
.append("subType", "04")))))))
.append("properties", new Document()
.append("ssn", new Document().append("encrypt", new Document()
.append("bsonType", "int")
.append("algorithm", "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic")))
.append("bloodType", new Document().append("encrypt", new Document()
.append("bsonType", "string")
.append("algorithm", "AEAD_AES_256_CBC_HMAC_SHA_512-Random")))
.append("medicalRecords", new Document().append("encrypt", new Document()
.append("bsonType", "array")
.append("algorithm", "AEAD_AES_256_CBC_HMAC_SHA_512-Random")))
.append("insurance", new Document()
.append("bsonType", "object")
.append("properties",
new Document().append("policyNumber", new Document().append("encrypt", new Document()
.append("bsonType", "int")
.append("algorithm", "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"))))));
HashMap<String, BsonDocument> schemaMap = new HashMap<String, BsonDocument>();
schemaMap.put("medicalRecords.patients", BsonDocument.parse(jsonSchema.toJson()));
dataKey = "<Your base64 DEK ID>";
const schema = {
bsonType: "object",
encryptMetadata: {
keyId: [new Binary(Buffer.from(dataKey, "base64"), 4)],
},
properties: {
insurance: {
bsonType: "object",
properties: {
policyNumber: {
encrypt: {
bsonType: "int",
algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
},
},
},
},
medicalRecords: {
encrypt: {
bsonType: "array",
algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
},
},
bloodType: {
encrypt: {
bsonType: "string",
algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
},
},
ssn: {
encrypt: {
bsonType: "int",
algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
},
},
},
};
var patientSchema = {};
patientSchema[namespace] = schema;
dek_id = b"<paste-base-64-encoded-data-encryption-key-id>"
json_schema = {
"bsonType": "object",
"encryptMetadata": {"keyId": [Binary(base64.b64decode(dek_id), UUID_SUBTYPE)]},
"properties": {
"insurance": {
"bsonType": "object",
"properties": {
"policyNumber": {
"encrypt": {
"bsonType": "int",
"algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
}
}
},
},
"medicalRecords": {
"encrypt": {
"bsonType": "array",
"algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
}
},
"bloodType": {
"encrypt": {
"bsonType": "string",
"algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
}
},
"ssn": {
"encrypt": {
"bsonType": "int",
"algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
}
},
},
}
patient_schema = {"medicalRecords.patients": json_schema}
4
var mongoBinariesPath = "<Full path to your Automatic Encryption Shared Library>";
var extraOptions = new Dictionary<string, object>()
{
{ "cryptSharedLibPath", mongoBinariesPath },
};
extraOptions := map[string]interface{}{
"cryptSharedLibPath": "<Full path to your Automatic Encryption Shared Library>",
}
Map<String, Object> extraOptions = new HashMap<String, Object>();
extraOptions.put("cryptSharedLibPath", "<Full path to your Automatic Encryption Shared Library>"));
const extraOptions = {
cryptSharedLibPath: "<Full path to your Automatic Encryption Shared Library>",
};
extra_options = {
"cryptSharedLibPath": "<Full path to your Automatic Encryption Shared Library>"
}

Nota

Opciones de cifrado automático

Las opciones de cifrado automático proporcionan información de configuración a la biblioteca compartida de cifrado automático, que modifica el comportamiento de la aplicación al acceder a campos cifrados.

Para obtener más información sobre la librería Compartida de Cifrado Automático, consulta la página librería Compartida de Cifrado Automático para CSFLE.

5

Instancia un objeto cliente de MongoDB con la siguiente configuración de cifrado automático:

var clientSettings = MongoClientSettings.FromConnectionString(connectionString);
var autoEncryptionOptions = new AutoEncryptionOptions(
keyVaultNamespace: keyVaultNamespace,
kmsProviders: kmsProviders,
schemaMap: schemaMap,
extraOptions: extraOptions
);
clientSettings.AutoEncryptionOptions = autoEncryptionOptions;
var secureClient = new MongoClient(clientSettings);
autoEncryptionOpts := options.AutoEncryption().
SetKmsProviders(kmsProviders).
SetKeyVaultNamespace(keyVaultNamespace).
SetSchemaMap(schemaMap).
SetExtraOptions(extraOptions)
secureClient, 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() {
_ = secureClient.Disconnect(context.TODO())
}()
MongoClientSettings clientSettings = MongoClientSettings.builder()
.applyConnectionString(new ConnectionString(connectionString))
.autoEncryptionSettings(AutoEncryptionSettings.builder()
.keyVaultNamespace(keyVaultNamespace)
.kmsProviders(kmsProviders)
.schemaMap(schemaMap)
.extraOptions(extraOptions)
.build())
.build();
MongoClient mongoClientSecure = MongoClients.create(clientSettings);
const secureClient = new MongoClient(connectionString, {
autoEncryption: {
keyVaultNamespace,
kmsProviders,
schemaMap: patientSchema,
extraOptions: extraOptions,
},
});
fle_opts = AutoEncryptionOpts(
kms_providers, key_vault_namespace, schema_map=patient_schema, **extra_options
)
secureClient = MongoClient(connection_string, auto_encryption_opts=fle_opts)
5

Utiliza tu instancia de MongoClient habilitada para CSFLE para insertar un documento con campos cifrados en el namespace medicalRecords.patients usando el siguiente fragmento de código:

var sampleDocFields = new BsonDocument
{
{ "name", "Jon Doe" },
{ "ssn", 145014000 },
{ "bloodType", "AB-" },
{
"medicalRecords", new BsonArray
{
new BsonDocument("weight", 180),
new BsonDocument("bloodPressure", "120/80")
}
},
{
"insurance", new BsonDocument
{
{ "policyNumber", 123142 },
{ "provider", "MaestCare" }
}
}
};
// Construct an auto-encrypting client
var secureCollection = secureClient.GetDatabase(db).GetCollection<BsonDocument>(coll);
// Insert a document into the collection
secureCollection.InsertOne(sampleDocFields);
test_patient := map[string]interface{}{
"name": "Jon Doe",
"ssn": 241014209,
"bloodType": "AB+",
"medicalRecords": []map[string]interface{}{{
"weight": 180,
"bloodPressure": "120/80",
}},
"insurance": map[string]interface{}{
"provider": "MaestCare",
"policyNumber": 123142,
},
}
if _, err := secureClient.Database(dbName).Collection(collName).InsertOne(context.TODO(), test_patient); err != nil {
return fmt.Errorf("InsertOne error: %v", err)
}

Nota

En vez de crear un documento BSON sin procesar, puedes pasar una estructura con etiquetas bson directamente al controlador para su codificación.

ArrayList<Document> medicalRecords = new ArrayList<>();
medicalRecords.add(new Document().append("weight", "180"));
medicalRecords.add(new Document().append("bloodPressure", "120/80"));
Document insurance = new Document()
.append("policyNumber", 123142)
.append("provider", "MaestCare");
Document patient = new Document()
.append("name", "Jon Doe")
.append("ssn", 241014209)
.append("bloodType", "AB+")
.append("medicalRecords", medicalRecords)
.append("insurance", insurance);
mongoClientSecure.getDatabase(recordsDb).getCollection(recordsColl).insertOne(patient);
try {
const writeResult = await secureClient
.db(db)
.collection(coll)
.insertOne({
name: "Jon Doe",
ssn: 241014209,
bloodType: "AB+",
medicalRecords: [{ weight: 180, bloodPressure: "120/80" }],
insurance: {
policyNumber: 123142,
provider: "MaestCare",
},
});
} catch (writeError) {
console.error("writeError occurred:", writeError);
}
def insert_patient(
collection, name, ssn, blood_type, medical_records, policy_number, provider
):
insurance = {"policyNumber": policy_number, "provider": provider}
doc = {
"name": name,
"ssn": ssn,
"bloodType": blood_type,
"medicalRecords": medical_records,
"insurance": insurance,
}
collection.insert_one(doc)
medical_record = [{"weight": 180, "bloodPressure": "120/80"}]
insert_patient(
secureClient.medicalRecords.patients,
"Jon Doe",
241014209,
"AB+",
medical_record,
123142,
"MaestCare",
)

Cuando insertas un documento, tu cliente habilitado con CSFLE cifra los campos de tu documento de modo que se asemejan a lo siguiente:

{
"_id": { "$oid": "<_id of your document>" },
"name": "Jon Doe",
"ssn": {
"$binary": "<cipher-text>",
"$type": "6"
},
"bloodType": {
"$binary": "<cipher-text>",
"$type": "6"
},
"medicalRecords": {
"$binary": "<cipher-text>",
"$type": "6"
},
"insurance": {
"provider": "MaestCare",
"policyNumber": {
"$binary": "<cipher-text>",
"$type": "6"
}
}
}

Tip

Consultar: Código completo

Para ver el código completo para insertar un documento con campos cifrados, consulta nuestro repositorio de Github

Para ver el código completo para insertar un documento con campos cifrados, consulte nuestro repositorio de Github.

Para ver el código completo para insertar un documento con campos cifrados, consulte nuestro repositorio de Github.

Para ver el código completo para insertar un documento con campos cifrados, consulte nuestro repositorio de Github.

Para ver el código completo para insertar un documento con campos cifrados, consulte nuestro repositorio de Github.

6

Recupere el documento con campos cifrados que insertó en el paso Insertar un documento con campos cifrados de esta guía.

Para mostrar la funcionalidad de CSFLE, el siguiente snippet de código query tu documento con un cliente configurado para CSFLE automático, así como un cliente que no está configurado para CSFLE automático.

Console.WriteLine("Finding a document with regular (non-encrypted) client.");
var filter = Builders<BsonDocument>.Filter.Eq("name", "Jon Doe");
var regularResult = regularCollection.Find(filter).Limit(1).ToList()[0];
Console.WriteLine($"\n{regularResult}\n");
Console.WriteLine("Finding a document with encrypted client, searching on an encrypted field");
var ssnFilter = Builders<BsonDocument>.Filter.Eq("ssn", 145014000);
var secureResult = secureCollection.Find(ssnFilter).Limit(1).First();
Console.WriteLine($"\n{secureResult}\n");
fmt.Println("Finding a document with regular (non-encrypted) client.")
var resultRegular bson.M
err = regularClient.Database(dbName).Collection(collName).FindOne(context.TODO(), bson.D{{"name", "Jon Doe"}}).Decode(&resultRegular)
if err != nil {
panic(err)
}
outputRegular, err := json.MarshalIndent(resultRegular, "", " ")
if err != nil {
panic(err)
}
fmt.Printf("%s\n", outputRegular)
fmt.Println("Finding a document with encrypted client, searching on an encrypted field")
var resultSecure bson.M
err = secureClient.Database(dbName).Collection(collName).FindOne(context.TODO(), bson.D{{"ssn", "241014209"}}).Decode(&resultSecure)
if err != nil {
panic(err)
}
outputSecure, err := json.MarshalIndent(resultSecure, "", " ")
if err != nil {
panic(err)
}
fmt.Printf("%s\n", outputSecure)
System.out.println("Finding a document with regular (non-encrypted) client.");
Document docRegular = mongoClientRegular.getDatabase(recordsDb).getCollection(recordsColl).find(eq("name", "Jon Doe")).first();
System.out.println(docRegular.toJson());
System.out.println("Finding a document with encrypted client, searching on an encrypted field");
Document docSecure = mongoClientSecure.getDatabase(recordsDb).getCollection(recordsColl).find(eq("ssn", 241014209)).first();
System.out.println(docSecure.toJson());
console.log("Finding a document with regular (non-encrypted) client.");
console.log(
await regularClient.db(db).collection(coll).findOne({ name: /Jon/ })
);
console.log(
"Finding a document with encrypted client, searching on an encrypted field"
);
console.log(
await secureClient.db(db).collection(coll).findOne({ ssn: "241014209" })
);
print("Finding a document with regular (non-encrypted) client.")
result = regularClient.medicalRecords.patients.find_one({"name": "Jon Doe"})
pprint.pprint(result)
print("Finding a document with encrypted client, searching on an encrypted field")
pprint.pprint(secureClient.medicalRecords.patients.find_one({"ssn": 241014209}))

La salida del código snippet precedente debería verse así:

Finding a document with regular (non-encrypted) client.
{
_id: new ObjectId("629a452e0861b3130887103a"),
name: 'Jon Doe',
ssn: new Binary(Buffer.from("0217482732d8014cdd9ffdd6e2966e5e7910c20697e5f4fa95710aafc9153f0a3dc769c8a132a604b468732ff1f4d8349ded3244b59cbfb41444a210f28b21ea1b6c737508d9d30e8baa30c1d8070c4d5e26", "hex"), 6),
bloodType: new Binary(Buffer.from("0217482732d8014cdd9ffdd6e2966e5e79022e238536dfd8caadb4d7751ac940e0f195addd7e5c67b61022d02faa90283ab69e02303c7e4001d1996128428bf037dea8bbf59fbb20c583cbcff2bf3e2519b4", "hex"), 6),
'key-id': 'demo-data-key',
medicalRecords: new Binary(Buffer.from("0217482732d8014cdd9ffdd6e2966e5e790405163a3207cff175455106f57eef14e5610c49a99bcbd14a7db9c5284e45e3ee30c149354015f941440bf54725d6492fb3b8704bc7c411cff6c868e4e13c58233c3d5ed9593eca4e4d027d76d3705b6d1f3b3c9e2ceee195fd944b553eb27eee69e5e67c338f146f8445995664980bf0", "hex"), 6),
insurance: {
policyNumber: new Binary(Buffer.from("0217482732d8014cdd9ffdd6e2966e5e79108decd85c05be3fec099e015f9d26d9234605dc959cc1a19b63072f7ffda99db38c7b487de0572a03b2139ac3ee163bcc40c8508f366ce92a5dd36e38b3c742f7", "hex"), 6),
provider: 'MaestCare'
}
}
Finding a document with encrypted client, searching on an encrypted field
{
_id: new ObjectId("629a452e0861b3130887103a"),
name: 'Jon Doe',
ssn: 241014209,
bloodType: 'AB+',
'key-id': 'demo-data-key',
medicalRecords: [ { weight: 180, bloodPressure: '120/80' } ],
insurance: { policyNumber: 123142, provider: 'MaestCare' }
}

Tip

Consultar: Código completo

Para ver el código completo para encontrar un documento con campos cifrados, consulte nuestro repositorio de Github

Para ver el código completo para encontrar un documento con campos cifrados, consulta nuestro repositorio en Github.

Para ver el código completo para encontrar un documento con campos cifrados, consulta nuestro repositorio en Github.

Para ver el código completo para encontrar un documento con campos cifrados, consulta nuestro repositorio en Github.

Para ver el código completo para encontrar un documento con campos cifrados, consulta nuestro repositorio en Github.

Para ver un tutorial sobre CSFLE lista para producción con un KMS remoto, consulta Tutoriales de CSFLE.

Para aprender cómo funciona CSFLE, consulta Fundamentos de CSFLE.

Para obtener más información sobre los temas mencionados en esta guía, consulta los siguientes enlaces:

Volver

Instalación

En esta página