Overview
Esta guía le muestra cómo cifrar un documento con cifrado explícito y un controlador MongoDB.
Tras completar esta guía, podrá configurar un controlador para cifrar los campos de un documento mediante cifrado explícito. Con este conocimiento, podrá crear una aplicación cliente que utilice cifrado explícito con descifrado automático.
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 demuestra cómo crear una aplicación habilitada para cifrado consultable que utiliza un sistema de administración de claves remoto, consulte Tutoriales.
Antes de empezar
Para completar y ejecutar el código de esta guía, debe configurar su entorno de desarrollo como se muestra en la página Requisitos de instalación.
Tip
Ver: Solicitud completa
Para ver el código completo de la aplicación que realice en esta guía, seleccione la pestaña correspondiente a su controlador MongoDB preferido y siga el enlace proporcionado:
Procedimiento
Crear una clave maestra de cliente
Debe crear una Clave Maestra de Cliente (CMK) para realizar cifrado consultable.
Cree una clave maestra de cliente de 96bytes y guárdela en el archivo master-key.txt:
openssl rand 96 > master-key.txt
Nota
Utilice un lenguaje de programación para crear una clave maestra de cliente
Si prefiere utilizar su lenguaje de programación preferido para generar su CMK, puede ver fragmentos de código que demuestran cómo generar una clave maestra de cliente en cada uno de los lenguajes admitidos en esta guía en GitHub.
Advertencia
No utilice un archivo de clave local en producción
Un archivo de clave local en su sistema de archivos no es seguro 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 utilizar un KMS remoto en su implementación de cifrado consultable, consulte la guía de tutoriales.
Cree un índice único en su colección de Key Vault
Cree un índice único en el campo keyAltNames en su colección encryption.__keyVault.
Seleccione la pestaña correspondiente a su controlador MongoDB preferido:
var connectionString = "<Your MongoDB URI>"; var keyVaultNamespace = CollectionNamespace.FromFullName("encryption.__keyVault"); var keyVaultClient = new MongoClient(connectionString); var indexOptions = new CreateIndexOptions<BsonDocument> { Unique = true, 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.DatabaseName); // Drop the Key Vault Collection in case you created this collection // in a previous run of this application. keyVaultDatabase.DropCollection(keyVaultNamespace.CollectionName); var keyVaultCollection = keyVaultDatabase.GetCollection<BsonDocument>(keyVaultNamespace.CollectionName); 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()) }() keyVaultDb := "encryption" keyVaultColl := "__keyVault" 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) } _, err = keyVaultClient.Database(keyVaultDb).Collection(keyVaultColl).Indexes().CreateOne(context.TODO(), keyVaultIndex) if err != nil { panic(err) }
String keyVaultDb = "encryption"; String keyVaultColl = "__keyVault"; MongoClient keyVaultClient = MongoClients.create(connectionString); String encryptedDbName = "medicalRecords"; String encryptedCollName = "patients"; // Drop the Key Vault Collection in case you created this collection // in a previous run of this application. keyVaultClient.getDatabase(keyVaultDb).getCollection(keyVaultColl).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 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(); 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) key_vault_client[key_vault_db][key_vault_coll].create_index( [("keyAltNames", ASCENDING)], unique=True, partialFilterExpression={"keyAltNames": {"$exists": True}}, )
Cree sus claves de cifrado de datos y su colección cifrada
Lea la clave maestra del cliente y especifique la configuración del proveedor KMS
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.
Pasa el valor llave maestra de cliente a los ajustes de tu proveedor de KMS. El cliente utiliza estos ajustes para descubrir la llave maestra de cliente. Configura el nombre del proveedor en local para informar al controlador que está utilizando un proveedor local de claves.
Seleccione la pestaña correspondiente a su controlador MongoDB preferido:
var kmsProviders = new Dictionary<string, IReadOnlyDictionary<string, object>>(); const string provider = "local"; var localMasterKeyBase64Read = File.ReadAllText("master-key.txt"); 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) } 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"; // WARNING: Do not use a local key file in a production application const localMasterKey = fs.readFileSync(path); const kmsProviders = { local: { key: localMasterKey, }, };
provider = "local" path = "./master-key.txt" # WARNING: Do not use a local key file in a production application 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 }, }
Crea tus claves de cifrado de datos
Construya un cliente con su cadena de conexión MongoDB y el espacio de nombres de la colección Key Vault, y cree las claves de cifrado de datos:
Nota
Permisos del espacio de nombres de la colección Key Vault
La colección Key Vault se encuentra en el encryption.__keyVault espacio de nombres. Asegúrese de que el usuario de la base de datos que su aplicación usa para conectarse a MongoDB tenga permisos de lectura y escritura en este espacio de nombres.
var clientEncryptionOptions = new ClientEncryptionOptions( keyVaultClient, keyVaultNamespace, kmsProviders: kmsProviders ); var clientEncryption = new ClientEncryption(clientEncryptionOptions); var dataKeyOptions1 = new DataKeyOptions(alternateKeyNames: new List<string> { "dataKey1" }); var dataKeyOptions2 = new DataKeyOptions(alternateKeyNames: new List<string> { "dataKey2" }); BsonBinaryData CreateKeyGetID(DataKeyOptions options) { var dateKeyGuid = clientEncryption.CreateDataKey(provider, options, CancellationToken.None); return new BsonBinaryData(dateKeyGuid, GuidRepresentation.Standard); } var dataKeyId1 = CreateKeyGetID(dataKeyOptions1); var dataKeyId2 = CreateKeyGetID(dataKeyOptions2); var dataKeyId3 = CreateKeyGetID(dataKeyOptions3); var dataKeyId4 = CreateKeyGetID(dataKeyOptions4);
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()) }() dataKeyOpts1 := options.DataKey(). SetKeyAltNames([]string{"demoDataKey1"}) dataKeyID1, err := clientEnc.CreateDataKey(context.TODO(), provider, dataKeyOpts1) if err != nil { return fmt.Errorf("create data key error %v", err) } dataKeyOpts2 := options.DataKey(). SetKeyAltNames([]string{"demoDataKey2"}) dataKeyID2, err := clientEnc.CreateDataKey(context.TODO(), provider, dataKeyOpts2) if err != nil { return fmt.Errorf("create data key error %v", err) }
String keyVaultNamespace = keyVaultDb + "." + keyVaultColl; ClientEncryptionSettings clientEncryptionSettings = ClientEncryptionSettings.builder() .keyVaultMongoClientSettings(MongoClientSettings.builder() .applyConnectionString(new ConnectionString(connectionString)) .build()) .keyVaultNamespace(keyVaultNamespace) .kmsProviders(kmsProviders) .build(); ClientEncryption clientEncryption = ClientEncryptions.create(clientEncryptionSettings); List<String> keyAlts1 = new ArrayList<String>(); keyAlts1.add("dataKey1"); BsonBinary dataKeyId1 = clientEncryption.createDataKey(kmsProvider, new DataKeyOptions() .keyAltNames(keyAlts1)); List<String> keyAlts2 = new ArrayList<String>(); keyAlts2.add("dataKey2"); BsonBinary dataKeyId2 = clientEncryption.createDataKey(kmsProvider, new DataKeyOptions() .keyAltNames(keyAlts2));
const clientEnc = new ClientEncryption(keyVaultClient, { keyVaultNamespace: keyVaultNamespace, kmsProviders: kmsProviders, }); const dek1 = await clientEnc.createDataKey(provider, { keyAltNames: ["dataKey1"], }); const dek2 = await clientEnc.createDataKey(provider, { keyAltNames: ["dataKey2"], });
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_1 = client_encryption.create_data_key(provider, key_alt_names=["dataKey1"]) data_key_id_2 = client_encryption.create_data_key(provider, key_alt_names=["dataKey2"])
Crea tu colección cifrada
Utilice una instancia MongoClient habilitada para cifrado consultable para especificar qué campos debe cifrar y crear su colección cifrada:
var encryptedCollectionNamespace = CollectionNamespace.FromFullName("medicalRecords.patients"); var encryptedFieldsMap = new Dictionary<string, BsonDocument> { { encryptedCollectionNamespace.FullName, new BsonDocument { { "fields", new BsonArray { new BsonDocument { {"keyId", dataKeyId1}, {"path", new BsonString("patientId")}, {"bsonType", new BsonString("int")}, { "queries", new BsonDocument { {"queryType", new BsonString("equality")} } } }, new BsonDocument { {"keyId", dataKeyId2}, {"path", new BsonString("medications")}, {"bsonType", new BsonString("array")}, }, } } } } }; var extraOptions = new Dictionary<string, object>() { { "cryptSharedLibPath", "<path to crypt_shared library>" }, }; var autoEncryptionOptions = new AutoEncryptionOptions( keyVaultNamespace, kmsProviders, encryptedFieldsMap: encryptedFieldsMap, extraOptions: extraOptions); var clientSettings = MongoClientSettings.FromConnectionString(connectionString); clientSettings.AutoEncryptionOptions = autoEncryptionOptions; var secureClient = new MongoClient(clientSettings); var encryptedDatabase = secureClient.GetDatabase(encryptedCollectionNamespace.DatabaseNamespace.DatabaseName); // Drop the encrypted collection in case you created this collection // in a previous run of this application. encryptedDatabase.DropCollection(encryptedCollectionNamespace.CollectionName); encryptedDatabase.CreateCollection(encryptedCollectionNamespace.CollectionName); Console.WriteLine("Created encrypted collection!");
dbName := "medicalRecords" collName := "patients" encNamespace := (dbName + "." + collName) encryptedFieldsMap := bson.M{ encNamespace: bson.M{ "fields": []bson.M{ { "path": "patientId", "bsonType": "int", "keyId": dataKeyID1, "queries": []bson.M{ { "queryType": "equality", }, }, }, { "path": "medications", "bsonType": "array", "keyId": dataKeyID2, }, }, }, } extraOptions := map[string]interface{}{ "cryptSharedLibPath": "<Your Crypt Shared lib Path>", } autoEncryptionOpts := options.AutoEncryption(). SetKmsProviders(kmsProviders). SetKeyVaultNamespace(keyVaultNamespace). SetEncryptedFieldsMap(encryptedFieldsMap). 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()) }() // Drop the encrypted collection in case you created this collection // in a previous run of this application. if err = secureClient.Database(dbName).Collection(collName).Drop(context.TODO()); err != nil { log.Fatalf("Collection.Drop error: %v", err) } err = secureClient.Database(dbName).CreateCollection(context.TODO(), collName) if err != nil { return fmt.Errorf("Error creating collection: %v", err) }
String encryptedNameSpace = encryptedDbName + "." + encryptedCollName; BsonDocument encFields = new BsonDocument().append("fields", new BsonArray(Arrays.asList( new BsonDocument().append("keyId", dataKeyId1) .append("path", new BsonString("patientId")) .append("bsonType", new BsonString("int")) .append("queries", new BsonDocument().append("queryType", new BsonString("equality"))), new BsonDocument().append("keyId", dataKeyId2) .append("path", new BsonString("medications")) .append("bsonType", new BsonString("array")), ))); Map<String, BsonDocument> encryptedFieldsMap = new HashMap<String, BsonDocument>(); encryptedFieldsMap.put(encryptedNameSpace, encFields); Map<String, Object> extraOptions = new HashMap<String, Object>(); extraOptions.put("cryptSharedLibPath", "<path to crypt_shared>"); MongoClientSettings clientSettings = MongoClientSettings.builder() .applyConnectionString(new ConnectionString(connectionString)) .autoEncryptionSettings(AutoEncryptionSettings.builder() .keyVaultNamespace(keyVaultNamespace) .kmsProviders(kmsProviders) .encryptedFieldsMap(encryptedFieldsMap) .extraOptions(extraOptions) .build()) .build(); MongoClient mongoClientSecure = MongoClients.create(clientSettings); MongoDatabase encDb = mongoClientSecure.getDatabase(encryptedDbName); // Drop the encrypted collection in case you created this collection // in a previous run of this application. encDb.getCollection(encryptedCollName).drop(); encDb.createCollection(encryptedCollName);
const encryptedFieldsMap = { [`${secretDB}.${secretCollection}`]: { fields: [ { keyId: dek1, path: "patientId", bsonType: "int", queries: { queryType: "equality" }, }, { keyId: dek2, path: "medications", bsonType: "array", }, ], }, }; const extraOptions = { cryptSharedLibPath: "<path to FLE Shared Library>", }; const encClient = new MongoClient(uri, { autoEncryption: { keyVaultNamespace, kmsProviders, extraOptions, encryptedFieldsMap, }, }); await encClient.connect(); const newEncDB = encClient.db(secretDB); // Drop the encrypted collection in case you created this collection // in a previous run of this application. await newEncDB.dropDatabase(); await newEncDB.createCollection(secretCollection); console.log("Created encrypted collection!");
encrypted_db_name = "medicalRecords" encrypted_coll_name = "patients" encrypted_fields_map = { f"{encrypted_db_name}.{encrypted_coll_name}": { "fields": [ { "keyId": data_key_id_1, "path": "patientId", "bsonType": "int", "queries": {"queryType": "equality"}, }, { "keyId": data_key_id_2, "path": "medications", "bsonType": "array", }, ], }, } key_vault_namespace = "encryption.__keyVault" auto_encryption = AutoEncryptionOpts( kms_providers, key_vault_namespace, encrypted_fields_map=encrypted_fields_map, schema_map=None, crypt_shared_lib_path="<path to FLE Shared Library>", ) secure_client = MongoClient(connection_string, auto_encryption_opts=auto_encryption) # Drop the encrypted collection in case you created this collection # in a previous run of this application. secure_client.drop_database(encrypted_db_name) encrypted_db = secure_client[encrypted_db_name] encrypted_db.create_collection(encrypted_coll_name) print("Created encrypted collection!")
La salida del código en esta sección debería parecerse a la siguiente:
Created encrypted collection!
Tip
Ver: Código completo
Para ver el código completo para crear una llave de cifrado de datos, consulta el repositorio de apps de ejemplo de Queryable Encryption.
Para ver el código completo para crear una llave de cifrado de datos, consulta el repositorio de apps de ejemplo de Queryable Encryption.
Para ver el código completo para crear una llave de cifrado de datos, consulta el repositorio de apps de ejemplo de Queryable Encryption.
Para ver el código completo para crear una llave de cifrado de datos, consulta el repositorio de apps de ejemplo de Queryable Encryption.
Para ver el código completo para crear una llave de cifrado de datos, consulta el repositorio de apps de ejemplo de Queryable Encryption.
Configure su MongoClient para lecturas y escrituras cifradas
Especifique el espacio de nombres de la colección Key Vault
Especifique encryption.__keyVault como el espacio de nombres de la colección Key Vault.
var connectionString = "<Your MongoDB URI>"; var keyVaultNamespace = CollectionNamespace.FromFullName("encryption.__keyVault"); var coll = "patients"; var db = "medicalRecords";
keyVaultColl := "__keyVault" keyVaultDb := "encryption" keyVaultNamespace := keyVaultDb + "." + keyVaultColl dbName := "medicalRecords" collName := "patients"
String db = "medicalRecords"; String coll = "patients"; String keyVaultDb = "encryption"; String keyVaultColl = "__keyVault"; String keyVaultNamespace = String.format("%1$s.%2$s", keyVaultDb, keyVaultColl); String connectionString = "<Your MongoDB URI>";
const eDB = "encryption"; const eKV = "__keyVault"; const keyVaultNamespace = `${eDB}.${eKV}`; const secretDB = "medicalRecords"; const secretCollection = "patients";
key_vault_namespace = "encryption.__keyVault" key_vault_db_name, key_vault_coll_name = key_vault_namespace.split(".", 1)
Especifique la clave maestra del cliente
Especifique el proveedor de KMS y especifique su clave maestra de cliente en línea:
var kmsProviders = new Dictionary<string, IReadOnlyDictionary<string, object>>(); const string provider = "local"; const string localMasterKeyPath = "master-key.txt"; var 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<>(); keyMap.put("key", localMasterKeyRead); Map<String, Map<String, Object>> kmsProviders = new HashMap<>(); kmsProviders.put(kmsProvider, keyMap);
const fs = require("fs"); const path = "./master-key.txt"; // WARNING: Do not use a local key file in a production application 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 }, }
Recuperar claves de cifrado de datos
Recupere las claves de cifrado de datos creadas en el paso Crear una clave de cifrado de datos de esta guía:
var regularClient = new MongoClient(connectionString); var keyVaultCollection = regularClient.GetDatabase(keyVaultNamespace.DatabaseNamespace.DatabaseName) .GetCollection<BsonDocument>(keyVaultNamespace.CollectionName); Guid GetKeyId(string altName) { var filter = Builders<BsonDocument>.Filter.Eq<BsonString>("keyAltNames", altName); return keyVaultCollection.Find(filter).First<BsonDocument>()["_id"].AsGuid; } var dataKeyId1 = GetKeyId("dataKey1"); var dataKeyId2 = GetKeyId("dataKey2");
uri := "<Your MongoDB URI>" regularClient, err := mongo.Connect(context.TODO(), options.Client().ApplyURI(uri)) if err != nil { panic(fmt.Errorf("Client connect error %v", err)) } var foundDoc1 bson.M err = regularClient.Database(keyVaultDb).Collection(keyVaultColl).FindOne(context.TODO(), bson.D{{"keyAltNames", "demoDataKey1"}}).Decode(&foundDoc1) if err != nil { panic(err) } var dataKeyID1 = foundDoc1["_id"].(primitive.Binary) var foundDoc2 bson.M err = regularClient.Database(keyVaultDb).Collection(keyVaultColl).FindOne(context.TODO(), bson.D{{"keyAltNames", "demoDataKey2"}}).Decode(&foundDoc2) if err != nil { panic(err) } var dataKeyID2 = foundDoc2["_id"].(primitive.Binary)
MongoClient client = MongoClients.create(connectionString); MongoCollection<Document> keyVaultClient = client.getDatabase(keyVaultDb).getCollection(keyVaultColl); BsonBinary dataKeyId1 = new BsonBinary(BsonBinarySubType.UUID_STANDARD, keyVaultClient.find(eq("keyAltNames", "dataKey1")).first().get("_id", Binary.class).getData()); BsonBinary dataKeyId2 = new BsonBinary(BsonBinarySubType.UUID_STANDARD, keyVaultClient.find(eq("keyAltNames", "dataKey2")).first().get("_id", Binary.class).getData());
const uri = "<Your MongoDB URI>"; const unencryptedClient = new MongoClient(uri); await unencryptedClient.connect(); const keyVaultClient = unencryptedClient.db(eDB).collection(eKV); const dek1 = await keyVaultClient.findOne({ keyAltNames: "dataKey1" }); const dek2 = await keyVaultClient.findOne({ keyAltNames: "dataKey2" });
connection_string = "<your connection string here>" client = MongoClient(connection_string) key_vault = client[key_vault_db_name][key_vault_coll_name] data_key_id_1 = key_vault.find_one({"keyAltNames": "dataKey1"})["_id"] data_key_id_2 = key_vault.find_one({"keyAltNames": "dataKey2"})["_id"]
Especifique la ruta de la biblioteca compartida de cifrado automático
var extraOptions = new Dictionary<string, object>() { {"cryptSharedLibPath", "<path to crypt_shared library>"}, };
extraOptions := map[string]interface{}{ "cryptSharedLibPath": "<path to crypt_shared library>", }
Map<String, Object> extraOptions = new HashMap<>(); extraOptions.put("cryptSharedLibPath", "<path to crypt_shared library>");
const extraOptions = { cryptSharedLibPath: "<path to crypt_shared library>", };
opts = AutoEncryptionOpts( kms_providers, key_vault.full_name, bypass_query_analysis=True, key_vault_client=client, crypt_shared_lib_path="<path to FLE Shared Library>", )
Tip
Obtén más información
Para obtener más información sobre la biblioteca a la que hace referencia esta ruta, consulte la página Biblioteca compartida de cifrado automático para cifrado consultable.
Crear un objeto MongoClient
Cree una instancia de un objeto MongoClient con las siguientes configuraciones de cifrado automático:
var clientSettings = MongoClientSettings.FromConnectionString(connectionString); var autoEncryptionOptions = new AutoEncryptionOptions( keyVaultNamespace, kmsProviders, bypassQueryAnalysis: true, extraOptions: extraOptions); clientSettings.AutoEncryptionOptions = autoEncryptionOptions; var secureClient = new MongoClient(clientSettings); var collection = secureClient.GetDatabase(db).GetCollection<BsonDocument>(coll);
autoEncryptionOpts := options.AutoEncryption(). SetKmsProviders(kmsProviders). SetKeyVaultNamespace(keyVaultNamespace). SetExtraOptions(extraOptions). SetBypassQueryAnalysis(true) 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()) }() var coll = secureClient.Database(dbName).Collection(collName)
MongoClientSettings clientSettings = MongoClientSettings.builder() .applyConnectionString(new ConnectionString(connectionString)) .autoEncryptionSettings(AutoEncryptionSettings.builder() .keyVaultNamespace(keyVaultNamespace) .kmsProviders(kmsProviders) .extraOptions(extraOptions) .bypassQueryAnalysis(true) .build()) .build(); MongoClient mongoClientSecure = MongoClients.create(clientSettings);
const encryptedClient = new MongoClient(uri, { autoEncryption: { kmsProviders: kmsProviders, keyVaultNamespace: keyVaultNamespace, bypassQueryAnalysis: true, keyVaultClient: unencryptedClient, extraOptions: extraOptions, }, }); await encryptedClient.connect();
encrypted_client = MongoClient(connection_string, auto_encryption_opts=opts) db = encrypted_client.medicalRecords coll = db.patients
Nota
Descifrado automático
Utilizamos una instancia MongoClient con cifrado automático habilitado para realizar el descifrado automático.
Para obtener más información sobre el cifrado explícito con descifrado automático, consulta la sección Fundamentos.
Crear un objeto ClientEncryption
Cree una instancia de un objeto ClientEncryption de la siguiente manera:
var clientEncryptionOptions = new ClientEncryptionOptions( keyVaultClient: regularClient, keyVaultNamespace: keyVaultNamespace, kmsProviders: kmsProviders ); var clientEncryption = new ClientEncryption(clientEncryptionOptions);
clientEncryptionOpts := options.ClientEncryption().SetKeyVaultNamespace(keyVaultNamespace).SetKmsProviders(kmsProviders) clientEnc, err := mongo.NewClientEncryption(regularClient, clientEncryptionOpts) if err != nil { panic(fmt.Errorf("NewClientEncryption error %v", err)) } defer func() { _ = clientEnc.Close(context.TODO()) }()
ClientEncryptionSettings clientEncryptionSettings = ClientEncryptionSettings.builder() .keyVaultMongoClientSettings(MongoClientSettings.builder() .applyConnectionString(new ConnectionString(connectionString)) .build()) .keyVaultNamespace(keyVaultNamespace) .kmsProviders(kmsProviders) .build(); ClientEncryption clientEncryption = ClientEncryptions.create(clientEncryptionSettings);
const encryption = new ClientEncryption(unencryptedClient, { keyVaultNamespace, kmsProviders, });
client_encryption = ClientEncryption( kms_providers, key_vault_namespace, client, client.codec_options )
Insertar un documento con campos cifrados
Utilice su instancia MongoClient habilitada para cifrado consultable para insertar un documento cifrado en el espacio de nombres medicalRecords.patients utilizando el siguiente fragmento de código:
var patientId = 12345678; var medications = new BsonArray { new BsonString("Atorvastatin"), new BsonString("Levothyroxine") }; var indexedEncrypted = clientEncryption.Encrypt( patientId, new EncryptOptions(algorithm: "Indexed", keyId: dataKeyId1, contentionFactor: 1), CancellationToken.None); var unindexedEncrypted = clientEncryption.Encrypt( medications, new EncryptOptions(algorithm: "Unindexed", keyId: dataKeyId2), CancellationToken.None); collection.InsertOne(new BsonDocument { { "firstName", "Jon" }, { "patientId", indexedEncrypted }, { "medications", unindexedEncrypted } });
patientIdRawValueType, patientIdRawValueData, err := bson.MarshalValue(12345678) if err != nil { panic(err) } patientIdRawValue := bson.RawValue{Type: patientIdRawValueType, Value: patientIdRawValueData} patientIdEncryptionOpts := options.Encrypt(). SetAlgorithm("Indexed"). SetKeyID(dataKeyID1). SetContentionFactor(1) patientIdEncryptedField, err := clientEnc.Encrypt( context.TODO(), patientIdRawValue, patientIdEncryptionOpts) if err != nil { panic(err) } medicationsRawValueType, medicationsRawValueData, err := bson.MarshalValue([]string{"Atorvastatin", "Levothyroxine"}) if err != nil { panic(err) } medicationsRawValue := bson.RawValue{Type: medicationsRawValueType, Value: medicationsRawValueData} medicationsEncryptionOpts := options.Encrypt(). SetAlgorithm("Unindexed"). SetKeyID(dataKeyID2) medicationsEncryptedField, err := clientEnc.Encrypt( context.TODO(), medicationsRawValue, medicationsEncryptionOpts) if err != nil { panic(err) } _, err = coll.InsertOne( context.TODO(), bson.D{{"firstName", "Jon"}, {"patientId", patientIdEncryptedField}, {"medications", medicationsEncryptedField}}) if err != nil { panic(err) }
BsonInt32 patientId = new BsonInt32(12345678); ArrayList<BsonString> medications = new ArrayList<>(); medications.add(new BsonString("Atorvastatin")); medications.add(new BsonString("Levothyroxine")); BsonBinary indexedEncrypted = clientEncryption.encrypt(patientId, new EncryptOptions("Indexed").keyId(dataKeyId1).contentionFactor(1L)); BsonBinary unindexedEncrypted = clientEncryption.encrypt(new BsonArray(medications), new EncryptOptions("Unindexed").keyId(dataKeyId2)); MongoCollection<BsonDocument> collection = mongoClientSecure.getDatabase(db).getCollection(coll, BsonDocument.class); collection.insertOne(new BsonDocument("firstName", new BsonString("Jon")).append("patientId", indexedEncrypted).append("medications", unindexedEncrypted));
const patientId = 12345678; const medications = ["Atorvastatin", "Levothyroxine"]; const indexedInsertPayload = await encryption.encrypt(patientId, { algorithm: "Indexed", keyId: dek1._id, contentionFactor: 1, }); const unindexedInsertPayload = await encryption.encrypt(medications, { algorithm: "Unindexed", keyId: dek2._id, }); const encryptedColl = encryptedClient .db(secretDB) .collection(secretCollection); await encryptedColl.insertOne({ firstName: "Jon", patientId: indexedInsertPayload, medications: unindexedInsertPayload, });
patientId = 12345678 medications = ["Atorvastatin", "Levothyroxine"] indexed_insert_payload = client_encryption.encrypt( patientId, Algorithm.INDEXED, data_key_id_1, contention_factor=1 ) unindexed_insert_payload = client_encryption.encrypt( medications, Algorithm.UNINDEXED, data_key_id_2 ) coll.insert_one( { "firstName": "Jon", "patientId": indexed_insert_payload, "medications": unindexed_insert_payload, } )
Cuando insertas un documento, tu cliente habilitado para Queryable Encryption cifra los campos de tu documento de manera que se asemeje a lo siguiente:
{ "_id": { "$oid": "6303e36053cc7ec2e6a630bd" }, "firstName": "Jon", "patientId": { "$binary": { "base64": "BxLJUBmg703civqMz8ASsD4QEYeSneOGiiYHfLE77ELEkp1EC/fXPrKCNRQl2mAFddszqDJ0P3znKrq0DVMEvJoU6wa0Ra+U+JjNVr8NtJE+TpTLCannY5Av6iGfLAaiHbM/E8Ftz1YCQsArQwuNp3wIV/GJPLa2662xsyk0wz7F6IRGC3FlnxpN4UIFaHE1M7Y6kEnx3tEy5uJBvU4Sex7I2H0kqHthClH77Q6xHIHc8H9d6upvgnEbkKBCnmc24A2pSG/xZ7LBsV3j5aOboPISuN/lvg==", "subType": "06" } }, "medications": { "$binary": { "base64": "BvOsveapfUxiuQxCMSM2fYIEyRlQaSqR+0NxlMarwurBflvoMz1FrSjSGgCVCpK8X+YrilP6Bac99kkaUmRJfjo4savxcjpOfEnUj5bHciPyfQBYmYF4PMLDtTTzGZpPilb9d5KgpIMBXxHi+dIcog==", "subType": "06" } }, "__safeContent__": [ { "$binary": { "base64": "ZLPIpgxzXpHUGrvdIHetwmMagR+mqvuUj5nzXNGf/WM=", "subType": "00" } } ] }
Advertencia
No modifique el campo __safeContent__
El campo __safeContent__ es esencial para el cifrado consultable. No modifique su contenido.
Tip
Ver: Código completo
Para ver el código completo para insertar un documento cifrado con cifrado explícito, consulta el Repositorio de la aplicación de ejemplo de Queryable Encryption.
Para ver el código completo para insertar un documento cifrado con cifrado explícito, consulta el Repositorio de la aplicación de ejemplo de Queryable Encryption.
Para ver el código completo para insertar un documento cifrado con cifrado explícito, consulta el Repositorio de la aplicación de ejemplo de Queryable Encryption.
Para ver el código completo para insertar un documento cifrado con cifrado explícito, consulta el Repositorio de la aplicación de ejemplo de Queryable Encryption.
Para ver el código completo para insertar un documento cifrado con cifrado explícito, consulta el Repositorio de la aplicación de ejemplo de Queryable Encryption.
Recupere su documento cifrado
Recupere el documento cifrado que insertó en el paso Insertar un documento con campos cifrados de esta guía a través de una consulta en un campo cifrado:
var findPayload = clientEncryption.Encrypt( patientId, new EncryptOptions(algorithm: "Indexed", keyId: dataKeyId1, queryType: "equality", contentionFactor: 1), CancellationToken.None); var doc = collection.Find(new BsonDocument { { "patientId", findPayload } }).Single(); Console.WriteLine($"Encrypted document: {doc}");
findPayloadRawValueType, findPayloadRawValueData, err := bson.MarshalValue(12345678) if err != nil { panic(err) } findPayloadRawValue := bson.RawValue{Type: findPayloadRawValueType, Value: findPayloadRawValueData} findPayloadEncryptionOpts := options.Encrypt(). SetAlgorithm("Indexed"). SetKeyID(dataKeyID1). SetQueryType("equality"). SetContentionFactor(1) findPayloadEncryptedField, err := clientEnc.Encrypt( context.TODO(), findPayloadRawValue, findPayloadEncryptionOpts) if err != nil { panic(err) } var resultSecure bson.M coll.FindOne(context.TODO(), bson.D{{"firstName", findPayloadEncryptedField}}).Decode(&resultSecure) if err != nil { panic(err) } outputSecure, err := json.MarshalIndent(resultSecure, "", " ") if err != nil { panic(err) } fmt.Printf("\nFound document searching on explicitly encrypted field:\n%s\n", outputSecure)
BsonBinary findPayloadEncrypted = clientEncryption.encrypt(patientId, new EncryptOptions("Indexed").keyId(dataKeyId1).queryType("equality").contentionFactor(1L)); BsonDocument result = collection.find(eq("patientId", findPayloadEncrypted)).first(); System.out.println("Finding a document with manually encrypted field: " + result.toJson());
const findPayload = await encryption.encrypt(patientId, { algorithm: "Indexed", keyId: dek1._id, queryType: "equality", contentionFactor: 1, }); console.log("Finding a document with manually encrypted field:");
find_payload = client_encryption.encrypt( patientId, Algorithm.INDEXED, data_key_id_1, query_type=QueryType.EQUALITY, contention_factor=1, ) doc = coll.find_one({"encryptedIndexed": find_payload}) print("\nReturned document:\n") pprint.pprint(doc)
La salida del fragmento de código anterior debe contener el siguiente documento:
{ "__safeContent__": [ { "Subtype": 0, "Data": "LfaIuWm9o30MIGrK7GGUoStJMSNOjRgbxy5q2TPiDes=" } ], "_id": "6303a770857952ca5e363fd2", "firstName": "Jon", "medications": ["Atorvastatin", "Levothyroxine"], "patientId": 12345678 }
Tip
Ver: Código completo
Para ver el código para recuperar su documento cifrado, consulte el repositorio de aplicaciones de muestra de cifrado consultable.
Para ver el código para recuperar su documento cifrado, consulte el repositorio de aplicaciones de muestra de cifrado consultable.
Para ver el código para recuperar su documento cifrado, consulte el repositorio de aplicaciones de muestra de cifrado consultable.
Para ver el código para recuperar su documento cifrado, consulte el repositorio de aplicaciones de muestra de cifrado consultable.
Para ver el código para recuperar su documento cifrado, consulte el repositorio de aplicaciones de muestra de cifrado consultable.
Obtén más información
Para ver un tutorial sobre el uso del cifrado consultable con un KMS remoto, consulte Tutoriales.
Para aprender cómo funciona Queryable Encryption, consulta Queryable Encryption con cifrado explícito.
Para obtener más información sobre los temas mencionados en esta guía, consulte los siguientes enlaces: