在 Azure 中使用自动 Queryable Encryption
在此页面上
Overview
本指南介绍如何使用 Azure Key Vault 构建启用了 Queryable Encryption 的应用程序。
在完成本指南中的步骤后,您应该具有:
托管在 Azure Key Vault 实例上的客户主密钥。
一个有效的客户端应用程序,使用客户主密钥插入加密文档。
开始之前
要完成并运行本指南中的代码,您需要按照安装要求页面所示设立开发环境。
提示
请参阅:完整应用程序
要查看您在本指南中创建的应用程序的完整代码,请选择与您的编程语言相对应的标签页,然后点击提供的链接:
设置 KMS
向 Azure 注册您的应用程序
登录到Azure 。
向 Azure Active Directory 注册您的应用程序
要在 Azure Active Directory 上注册应用程序,请按照 Microsoft 官方文档 注册应用程序到 Microsoft 身份平台 快速入门。
重要
记录凭证
确保记录以下凭证:
租户 ID
客户 ID
客户端密钥
在本教程的后面部分,您将需要它们来构造 kmsProviders
对象。
创建客户主密钥
创建 Azure Key Vault 和客户主密钥
要创建新的 Azure Key Vault 实例和客户主密钥,请遵循 Microsoft 官方文档 使用 Azure 门户从 Azure Key Vault 设置和检索密钥 快速入门。
重要
记录凭证
确保记录以下凭证:
密钥名称
密钥标识符(本指南后面称为
keyVaultEndpoint
)keyVersion
在本教程的后面内容中,您将需要它们来构造dataKeyOpts
对象。
创建应用程序
在密钥保管库集合上创建唯一索引
在你的encryption.__keyVault
collection中的keyAltNames
字段上创建唯一索引。
选择与所需的 MongoDB 驱动程序对应的标签页:
const uri = "<Your Connection String>"; const keyVaultClient = Mongo(uri); const keyVaultDB = keyVaultClient.getDB(keyVaultDatabase); // Drop the Key Vault Collection in case you created this collection // in a previous run of this application. keyVaultDB.dropDatabase(); keyVaultDB.createCollection(keyVaultCollection); const keyVaultColl = keyVaultDB.getCollection(keyVaultCollection); keyVaultColl.createIndex( { keyAltNames: 1 }, { unique: true, partialFilterExpression: { keyAltNames: { $exists: true } }, } );
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 connectionString = "<Your MongoDB URI>"; 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}}, )
创建你的数据加密密钥和加密collection
添加 Azure Key Vault 档案
将服务帐户凭证添加到启用了 Queryable Encryption 的客户端代码中。
选择与所需的 MongoDB 驱动程序对应的标签页:
提示
您在本指南的“向 Azure 注册应用程序”步骤中记录了 Azure Key Vault 档案。
const provider = "azure"; const kmsProviders = { azure: { tenantId: "<Your Tenant ID>", clientId: "<Your Client ID>", clientSecret: "<Your Client Secret>", }, };
var kmsProviders = new Dictionary<string, IReadOnlyDictionary<string, object>>(); const string provider = "azure"; var azureKmsOptions = new Dictionary<string, object> { { "tenantId", "<Your Azure Tenant ID>" }, { "clientId", "<Your Azure Client ID>" }, { "clientSecret", "<Your Azure Client Secret>" }, }; kmsProviders.Add(provider, azureKmsOptions);
provider := "azure" kmsProviders := map[string]map[string]interface{}{ provider: { "tenantId": "<Your Azure Tenant ID>", "clientId": "<Your Azure Client ID>", "clientSecret": "<Your Azure Client Secret>", }, }
String kmsProvider = "azure"; Map<String, Map<String, Object>> kmsProviders = new HashMap<String, Map<String, Object>>(); Map<String, Object> providerDetails = new HashMap<>(); providerDetails.put("tenantId", "<Azure account organization>"); providerDetails.put("clientId", "<Azure client ID>"); providerDetails.put("clientSecret", "<Azure client secret>"); kmsProviders.put(kmsProvider, providerDetails);
const provider = "azure"; const kmsProviders = { azure: { tenantId: "<Your Tenant ID>", clientId: "<Your Client ID>", clientSecret: "<Your Client Secret>", }, };
provider = "azure" kms_providers = { provider: { "tenantId": "<Azure account organization>", "clientId": "<Azure client ID>", "clientSecret": "<Azure client secret>", } }
添加您的密钥信息
更新以下代码以指定客户主密钥:
提示
您在本指南的 创建客户主密钥 步骤中记录了客户主密钥的 ARN 和地区。
const masterKey = { keyVaultEndpoint: "<Your Key Vault Endpoint>", keyName: "<Your Key Name>", };
DataKeyOptions GetDataKeyOptions(List<string> altNames) { kmsProviders.Add(provider, azureKmsOptions); var dataKeyOptions = new DataKeyOptions( alternateKeyNames: altNames, masterKey: new BsonDocument { { "keyName", "<Your Azure Key Name>" }, { "keyVaultEndpoint", "<Your Azure Key Vault Endpoint>" }, }); return dataKeyOptions; }
masterKey := map[string]interface{}{ "keyVaultEndpoint": "<Your Azure Key Vault Endpoint>", "keyName": "<Your Azure Key Name>", }
BsonDocument masterKeyProperties = new BsonDocument(); masterKeyProperties.put("provider", new BsonString(kmsProvider)); masterKeyProperties.put("keyName", new BsonString("<Azure key name>")); masterKeyProperties.put("keyVaultEndpoint", new BsonString("<Azure key vault endpoint"));
const masterKey = { keyVaultEndpoint: "<Your Key Vault Endpoint>", keyName: "<Your Key Name>", };
master_key = { "keyName": "<Azure key name>", "keyVersion": "<Azure key version>", "keyVaultEndpoint": "<Azure key vault endpoint/key identifier>", }
创建数据加密密钥
使用 MongoDB 连接字符串和密钥保管库集合命名空间构建客户端,并创建数据加密密钥:
注意
密钥保管库集合命名空间权限
本指南中的“密钥保管库集合”是encryption
数据库中的__keyVault
集合。 确保应用程序用于连接到 MongoDB 的数据库用户对encryption.__keyVault
命名空间具有ReadWrite权限。
const autoEncryptionOpts = { keyVaultNamespace: keyVaultNamespace, kmsProviders: kmsProviders, }; const encClient = Mongo(uri, autoEncryptionOpts); const keyVault = encClient.getKeyVault(); const dek1 = keyVault.createKey(provider, { masterKey: masterKey, keyAltNames: ["dataKey1"], }); const dek2 = keyVault.createKey(provider, { masterKey: masterKey, keyAltNames: ["dataKey2"], }); const dek3 = keyVault.createKey(provider, { masterKey: masterKey, keyAltNames: ["dataKey3"], }); const dek4 = keyVault.createKey(provider, { masterKey: masterKey, keyAltNames: ["dataKey4"], });
var clientEncryptionOptions = new ClientEncryptionOptions( keyVaultClient, keyVaultNamespace, kmsProviders: kmsProviders ); var clientEncryption = new ClientEncryption(clientEncryptionOptions); var dataKeyOptions1 = GetDataKeyOptions(new List<string> { "dataKey1" }); var dataKeyOptions2 = GetDataKeyOptions(new List<string> { "dataKey2" }); var dataKeyOptions3 = GetDataKeyOptions(new List<string> { "dataKey3" }); var dataKeyOptions4 = GetDataKeyOptions(new List<string> { "dataKey4" }); 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(). SetMasterKey(masterKey). 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(). SetMasterKey(masterKey). SetKeyAltNames([]string{"demoDataKey2"}) dataKeyID2, err := clientEnc.CreateDataKey(context.TODO(), provider, dataKeyOpts2) if err != nil { return fmt.Errorf("create data key error %v", err) } dataKeyOpts3 := options.DataKey(). SetMasterKey(masterKey). SetKeyAltNames([]string{"demoDataKey3"}) dataKeyID3, err := clientEnc.CreateDataKey(context.TODO(), provider, dataKeyOpts3) if err != nil { return fmt.Errorf("create data key error %v", err) } dataKeyOpts4 := options.DataKey(). SetMasterKey(masterKey). SetKeyAltNames([]string{"demoDataKey4"}) dataKeyID4, err := clientEnc.CreateDataKey(context.TODO(), provider, dataKeyOpts4) 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() .masterKey(masterKeyProperties) .keyAltNames(keyAlts1)); List<String> keyAlts2 = new ArrayList<String>(); keyAlts2.add("dataKey2"); BsonBinary dataKeyId2 = clientEncryption.createDataKey(kmsProvider, new DataKeyOptions() .masterKey(masterKeyProperties) .keyAltNames(keyAlts2)); List<String> keyAlts3 = new ArrayList<String>(); keyAlts3.add("dataKey3"); BsonBinary dataKeyId3 = clientEncryption.createDataKey(kmsProvider, new DataKeyOptions() .masterKey(masterKeyProperties) .keyAltNames(keyAlts3)); List<String> keyAlts4 = new ArrayList<String>(); keyAlts4.add("dataKey4"); BsonBinary dataKeyId4 = clientEncryption.createDataKey(kmsProvider, new DataKeyOptions() .masterKey(masterKeyProperties) .keyAltNames(keyAlts4));
const clientEnc = new ClientEncryption(keyVaultClient, { keyVaultNamespace: keyVaultNamespace, kmsProviders: kmsProviders, }); const dek1 = await clientEnc.createDataKey(provider, { masterKey: masterKey, keyAltNames: ["dataKey1"], }); const dek2 = await clientEnc.createDataKey(provider, { masterKey: masterKey, keyAltNames: ["dataKey2"], }); const dek3 = await clientEnc.createDataKey(provider, { masterKey: masterKey, keyAltNames: ["dataKey3"], }); const dek4 = await clientEnc.createDataKey(provider, { masterKey: masterKey, keyAltNames: ["dataKey4"], });
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, master_key=master_key, key_alt_names=["dataKey1"] ) data_key_id_2 = client_encryption.create_data_key( provider, master_key=master_key, key_alt_names=["dataKey2"] ) data_key_id_3 = client_encryption.create_data_key( provider, master_key=master_key, key_alt_names=["dataKey3"] ) data_key_id_4 = client_encryption.create_data_key( provider, master_key=master_key, key_alt_names=["dataKey4"] )
创建加密集合
使用已启用 Queryable Encryption 的MongoClient
实例指定必须加密的字段并创建你的加密 collection:
const encryptedFieldsMap = { [`${secretDB}.${secretCollection}`]: { fields: [ { keyId: dek1, path: "patientId", bsonType: "int", queries: { queryType: "equality" }, }, { keyId: dek2, path: "medications", bsonType: "array", }, { keyId: dek3, path: "patientRecord.ssn", bsonType: "string", queries: { queryType: "equality" }, }, { keyId: dek4, path: "patientRecord.billing", bsonType: "object", }, ], }, }; try { const autoEncryptionOptions = { keyVaultNamespace: keyVaultNamespace, kmsProviders: kmsProviders, encryptedFieldsMap: encryptedFieldsMap, }; const encClient = Mongo(uri, autoEncryptionOptions); const newEncDB = encClient.getDB(secretDB); // Drop the encrypted collection in case you created this collection // in a previous run of this application. newEncDB.dropDatabase(); newEncDB.createCollection(secretCollection); console.log("Created encrypted collection!");
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")}, }, new BsonDocument { {"keyId", dataKeyId3}, {"path", new BsonString("patientRecord.ssn")}, {"bsonType", new BsonString("string")}, { "queries", new BsonDocument { {"queryType", new BsonString("equality")} } } }, new BsonDocument { {"keyId", dataKeyId4}, {"path", new BsonString("patientRecord.billing")}, {"bsonType", new BsonString("object")}, }, } } } } }; 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, }, { "path": "patientRecord.ssn", "bsonType": "string", "keyId": dataKeyID3, "queries": []bson.M{ { "queryType": "equality", }, }, }, { "path": "patientRecord.billing", "bsonType": "object", "keyId": dataKeyID4, }, }, }, } 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")), new BsonDocument().append("keyId", dataKeyId3) .append("path", new BsonString("patientRecord.ssn")) .append("bsonType", new BsonString("string")) .append("queries", new BsonDocument().append("queryType", new BsonString("equality"))), new BsonDocument().append("keyId", dataKeyId4) .append("path", new BsonString("patientRecord.billing")) .append("bsonType", new BsonString("object")) ))); 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", }, { keyId: dek3, path: "patientRecord.ssn", bsonType: "string", queries: { queryType: "equality" }, }, { keyId: dek4, path: "patientRecord.billing", bsonType: "object", }, ], }, }; 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", }, { "keyId": data_key_id_3, "path": "patientRecord.ssn", "bsonType": "string", "queries": {"queryType": "equality"}, }, { "keyId": data_key_id_4, "path": "patientRecord.billing", "bsonType": "object", }, ], }, } 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!")
提示
了解详情
要查看显示使用 Azure Key Vault 时客户端应用程序如何创建数据加密密钥的图表,请参阅架构。
要详细了解创建使用 Azure Key Vault 中托管的客户主密钥加密的数据加密密钥的选项,请参阅kmsProviders 对象和dataKeyOpts 对象。
提示
请参阅:完整代码
要查看制作数据加密密钥的完整代码,请参阅 Queryable Encryption 示例应用程序存储库。
要查看制作数据加密密钥的完整代码,请参阅 Queryable Encryption 示例应用程序存储库。
要查看制作数据加密密钥的完整代码,请参阅 Queryable Encryption 示例应用程序存储库。
要查看制作数据加密密钥的完整代码,请参阅 Queryable Encryption 示例应用程序存储库。
要查看制作数据加密密钥的完整代码,请参阅 Queryable Encryption 示例应用程序存储库。
要查看制作数据加密密钥的完整代码,请参阅 Queryable Encryption 示例应用程序存储库。
配置 MongoClient 以进行加密读取和写入
指定密钥保管库集合命名空间
指定 encryption.__keyVault
以作为密钥保管库集合命名空间。
const keyVaultDB = "encryption"; const keyVaultColl = "__keyVault"; const keyVaultNamespace = `${keyVaultDB}.${keyVaultColl}`; const secretDB = "medicalRecords"; const secretCollection = "patients";
var keyVaultNamespace = CollectionNamespace.FromFullName("encryption.__keyVault");
keyVaultColl := "__keyVault" keyVaultDb := "encryption" keyVaultNamespace := keyVaultDb + "." + keyVaultColl
String keyVaultDb = "encryption"; String keyVaultColl = "__keyVault"; String keyVaultNamespace = keyVaultDb + "." + keyVaultColl;
const eDB = "encryption"; const eKV = "__keyVault"; const keyVaultNamespace = `${eDB}.${eKV}`;
key_vault_db = "encryption" key_vault_coll = "__keyVault" key_vault_namespace = "encryption.__keyVault"
指定 Azure 档案
指定azure
KMS 提供商和您的 Azure 档案:
const kmsProviders = { azure: { tenantId: "<Your Tenant ID>", clientId: "<Your Client ID>", clientSecret: "<Your Client Secret>", }, };
var kmsProviders = new Dictionary<string, IReadOnlyDictionary<string, object>>(); const string provider = "azure"; var azureKmsOptions = new Dictionary<string, object> { { "tenantId", "<Your Azure Tenant ID>" }, { "clientId", "<Your Azure Client ID>" }, { "clientSecret", "<Your Azure Client Secret>" }, }; kmsProviders.Add(provider, azureKmsOptions);
kmsProviders := map[string]map[string]interface{}{ "azure": { "tenantId": "<Your Azure Tenant ID>", "clientId": "<Your Azure Client ID>", "clientSecret": "<Your Azure Client Secret>", }, }
String kmsProvider = "azure"; Map<String, Map<String, Object>> kmsProviders = new HashMap<String, Map<String, Object>>(); Map<String, Object> providerDetails = new HashMap<>(); providerDetails.put("tenantId", "<Azure account organization>"); providerDetails.put("clientId", "<Azure client ID>"); providerDetails.put("clientSecret", "<Azure client secret>"); kmsProviders.put(kmsProvider, providerDetails);
const kmsProviders = { azure: { tenantId: "<Your Tenant ID>", clientId: "<Your Client ID>", clientSecret: "<Your Client Secret>", }, };
provider = "azure" kms_providers = { provider: { "tenantId": "<Azure account organization>", "clientId": "<Azure client ID>", "clientSecret": "<Azure client secret>", } }
为collection创建加密字段映射
const uri = "<Your Connection String>"; const unencryptedClient = Mongo(uri); const autoEncryptionOpts = { kmsProviders, keyVaultNamespace }; const encClient = Mongo(uri, autoEncryptionOpts); const keyVault = encClient.getKeyVault(); const keyVaultClient = unencryptedClient .getDB(keyVaultDB) .getCollection(keyVaultColl); const dek1 = keyVaultClient.findOne({ keyAltNames: "dataKey1" }); const dek2 = keyVaultClient.findOne({ keyAltNames: "dataKey2" }); const dek3 = keyVaultClient.findOne({ keyAltNames: "dataKey3" }); const dek4 = keyVaultClient.findOne({ keyAltNames: "dataKey4" }); const secretDB = "medicalRecords"; const secretColl = "patients"; const encryptedFieldsMap = { [`${secretDB}.${secretColl}`]: { fields: [ { keyId: dek1._id, path: "patientId", bsonType: "int", queries: { queryType: "equality" }, }, { keyId: dek2._id, path: "medications", bsonType: "array", }, { keyId: dek3._id, path: "patientRecord.ssn", bsonType: "string", queries: { queryType: "equality" }, }, { keyId: dek4._id, path: "patientRecord.billing", bsonType: "object", }, ], }, };
var regularClient = new MongoClient(connectionString); var keyVaultCollection = regularClient.GetDatabase(keyVaultNamespace.DatabaseNamespace.DatabaseName) .GetCollection<BsonDocument>(keyVaultNamespace.CollectionName); BsonBinaryData GetKeyId(string altName) { var filter = Builders<BsonDocument>.Filter.Eq<BsonString>("keyAltNames", altName); return keyVaultCollection.Find(filter).First<BsonDocument>()["_id"].AsBsonBinaryData; } var dataKeyId1 = GetKeyId("dataKey1"); var dataKeyId2 = GetKeyId("dataKey2"); var dataKeyId3 = GetKeyId("dataKey3"); var dataKeyId4 = GetKeyId("dataKey4"); 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")}, }, new BsonDocument { {"keyId", dataKeyId3}, {"path", new BsonString("patientRecord.ssn")}, {"bsonType", new BsonString("string")}, { "queries", new BsonDocument { {"queryType", new BsonString("equality")} } } }, new BsonDocument { {"keyId", dataKeyId4}, {"path", new BsonString("patientRecord.billing")}, {"bsonType", new BsonString("object")}, }, } } } } };
regularClient, err := mongo.Connect(context.TODO(), options.Client().ApplyURI(uri)) if err != nil { return fmt.Errorf("Connect error for regular client: %v", err) } defer func() { _ = regularClient.Disconnect(context.TODO()) }() 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) var foundDoc3 bson.M err = regularClient.Database(keyVaultDb).Collection(keyVaultColl).FindOne(context.TODO(), bson.D{{"keyAltNames", "demoDataKey3"}}).Decode(&foundDoc3) if err != nil { panic(err) } var dataKeyID3 = foundDoc3["_id"].(primitive.Binary) var foundDoc4 bson.M err = regularClient.Database(keyVaultDb).Collection(keyVaultColl).FindOne(context.TODO(), bson.D{{"keyAltNames", "demoDataKey4"}}).Decode(&foundDoc4) if err != nil { panic(err) } var dataKeyID4 = foundDoc4["_id"].(primitive.Binary) encryptedFieldsMap := bson.M{ "medicalRecords.patients": bson.M{ "fields": []bson.M{ { "path": "patientId", "bsonType": "int", "keyId": dataKeyID1, "queries": []bson.M{ { "queryType": "equality", }, }, }, { "path": "medications", "bsonType": "array", "keyId": dataKeyID2, }, { "path": "patientRecord.ssn", "bsonType": "string", "keyId": dataKeyID3, "queries": []bson.M{ { "queryType": "equality", }, }, }, { "path": "patientRecord.billing", "bsonType": "object", "keyId": dataKeyID4, }, }, }, }
MongoClient regularClient = MongoClients.create(connectionString); MongoCollection<Document> keyVaultClient = regularClient.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()); BsonBinary dataKeyId3 = new BsonBinary(BsonBinarySubType.UUID_STANDARD, keyVaultClient.find(eq("keyAltNames", "dataKey3")).first().get("_id", Binary.class).getData()); BsonBinary dataKeyId4 = new BsonBinary(BsonBinarySubType.UUID_STANDARD, keyVaultClient.find(eq("keyAltNames", "dataKey4")).first().get("_id", Binary.class).getData()); 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")), new BsonDocument().append("keyId", dataKeyId3) .append("path", new BsonString("patientRecord.ssn")) .append("bsonType", new BsonString("string")) .append("queries", new BsonDocument().append("queryType", new BsonString("equality"))), new BsonDocument().append("keyId", dataKeyId4) .append("path", new BsonString("patientRecord.billing")) .append("bsonType", new BsonString("object"))))); Map<String, BsonDocument> encryptedFieldsMap = new HashMap<String, BsonDocument>(); encryptedFieldsMap.put(encryptedNameSpace, encFields);
const uri = "<Your Connection String>"; 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" }); const dek3 = await keyVaultClient.findOne({ keyAltNames: "dataKey3" }); const dek4 = await keyVaultClient.findOne({ keyAltNames: "dataKey4" }); const secretDB = "medicalRecords"; const secretCollection = "patients"; const encryptedFieldsMap = { [`${secretDB}.${secretCollection}`]: { fields: [ { keyId: dek1._id, path: "patientId", bsonType: "int", queries: { queryType: "equality" }, }, { keyId: dek2._id, path: "medications", bsonType: "array", }, { keyId: dek3._id, path: "patientRecord.ssn", bsonType: "string", queries: { queryType: "equality" }, }, { keyId: dek4._id, path: "patientRecord.billing", bsonType: "object", }, ], }, };
connection_string = "<your connection string here>" unencryptedClient = MongoClient(connection_string) keyVaultClient = unencryptedClient[key_vault_db][key_vault_coll] data_key_id_1 = keyVaultClient.find_one({"keyAltNames": "dataKey1"})["_id"] data_key_id_2 = keyVaultClient.find_one({"keyAltNames": "dataKey2"})["_id"] data_key_id_3 = keyVaultClient.find_one({"keyAltNames": "dataKey3"})["_id"] data_key_id_4 = keyVaultClient.find_one({"keyAltNames": "dataKey4"})["_id"] 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", }, { "keyId": data_key_id_3, "path": "patientRecord.ssn", "bsonType": "string", "queries": {"queryType": "equality"}, }, { "keyId": data_key_id_4, "path": "patientRecord.billing", "bsonType": "object", }, ], }, }
指定自动加密共享库位置
// mongosh does not require you to specify the // location of the Automatic Encryption Shared Library
var extraOptions = new Dictionary<string, object>() { { "cryptSharedLibPath", "<path to crypt_shared library>" }, };
extraOptions := map[string]interface{}{ "cryptSharedLibPath": "<Your Crypt Shared lib Path>", }
Map<String, Object> extraOptions = new HashMap<String, Object>(); extraOptions.put("cryptSharedLibPath", "<path to crypt_shared>");
const extraOptions = { cryptSharedLibPath: "<path to FLE Shared Library>", };
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>", )
注意
自动加密选项
自动加密选项向自动加密共享库提供配置信息,这将修改应用程序在访问加密字段时的行为。
要了解有关自动加密共享库的更多信息,请参阅 Queryable Encryption 的自动加密共享库页面。
创建 MongoClient
使用以下自动加密设置实例化 MongoDB 客户端对象:
const autoEncryptionOptions = { keyVaultNamespace: keyVaultNamespace, kmsProviders: kmsProviders, bypassQueryAnalysis: false, encryptedFieldsMap: encryptedFieldsMap, }; const encryptedClient = Mongo(uri, autoEncryptionOptions); const encryptedColl = encryptedClient .getDB(secretDB) .getCollection(secretColl); const unencryptedColl = unencryptedClient .getDB(secretDB) .getCollection(secretColl);
var clientSettings = MongoClientSettings.FromConnectionString(connectionString); var autoEncryptionOptions = new AutoEncryptionOptions( keyVaultNamespace, kmsProviders, encryptedFieldsMap: encryptedFieldsMap, extraOptions: extraOptions ); clientSettings.AutoEncryptionOptions = autoEncryptionOptions; var secureClient = new MongoClient(clientSettings);
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()) }()
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);
const encryptedClient = new MongoClient(uri, { autoEncryption: { keyVaultNamespace: keyVaultNamespace, kmsProviders: kmsProviders, extraOptions: extraOptions, encryptedFieldsMap: encryptedFieldsMap, }, }); await encryptedClient.connect();
secure_client = MongoClient(connection_string, auto_encryption_opts=auto_encryption)
插入具有加密字段的文档
使用已启用 Queryable Encryption 的实例MongoClient
,通过以下代码段将加密文档插入到命名空间medicalRecords.patients
中:
encryptedColl.insertOne({ firstName: "Jon", lastName: "Doe", patientId: 12345678, address: "157 Electric Ave.", patientRecord: { ssn: "987-65-4320", billing: { type: "Visa", number: "4111111111111111", }, }, medications: ["Atorvastatin", "Levothyroxine"], });
var sampleDocument = new BsonDocument { {"firstName", "Jon"}, {"lastName", "Doe"}, {"patientId", 12345678}, {"address", "157 Electric Ave."}, { "medications", new BsonArray { new BsonString("Atorvastatin"), new BsonString("Levothyroxine") } }, { "patientRecord", new BsonDocument { {"ssn", new BsonString("987-65-4320")}, { "billing", new BsonDocument { {"type", new BsonString("Visa")}, {"number", "4111111111111111"} } } } } }; var secureCollection = secureClient.GetDatabase(encryptedCollectionNamespace.DatabaseNamespace.DatabaseName) .GetCollection<BsonDocument>(encryptedCollectionNamespace.CollectionName); secureCollection.InsertOne(sampleDocument);
test_patient := map[string]interface{}{ "firstName": "Jon", "lastName": "Doe", "patientId": 12345678, "address": "157 Electric Ave.", "medications": []string{"Atorvastatin", "Levothyroxine"}, "patientRecord": map[string]interface{}{ "ssn": "987-65-4320", "billing": map[string]interface{}{ "type": "Visa", "number": "4111111111111111", }, }, } if _, err := secureClient.Database(dbName).Collection(collName).InsertOne(context.TODO(), test_patient); err != nil { return fmt.Errorf("InsertOne error: %v", err) }
ArrayList<String> medications = new ArrayList<>(); medications.add("Atorvastatin"); medications.add("Levothyroxine"); Document patientRecord = new Document() .append("ssn", "987-65-4320") .append("billing", new Document().append("type", "Visa").append("number", "4111111111111111")); Document patient = new Document() .append("firstName", "Jon") .append("lastName", "Doe") .append("patientId", 12345678) .append("address", "AB+") .append("medications", medications) .append("patientRecord", patientRecord); mongoClientSecure.getDatabase(encryptedDbName).getCollection(encryptedCollName).insertOne(patient);
const encryptedColl = encryptedClient .db(secretDB) .collection(secretCollection); await encryptedColl.insertOne({ firstName: "Jon", lastName: "Doe", patientId: 12345678, address: "157 Electric Ave.", patientRecord: { ssn: "987-65-4320", billing: { type: "Visa", number: "4111111111111111", }, }, medications: ["Atorvastatin", "Levothyroxine"], });
注意
您可以将带有bson
标签的结构体直接传递给驱动程序进行编码,而无需创建原始 BSON 文档。
encrypted_coll = secure_client[encrypted_db_name][encrypted_coll_name] encrypted_coll.insert_one( { "firstName": "Jon", "lastName": "Doe", "patientId": 12345678, "address": "157 Electric Ave.", "patientRecord": { "ssn": "987-65-4320", "billing": { "type": "Visa", "number": "4111111111111111", }, }, "medications": ["Atorvastatin", "Levothyroxine"], } )
插入文档时,启用了 Queryable Encryption 的客户端会对文档的字段进行加密,如下所示:
{ "_id": { "$oid": "<_id value>" }, "firstName": "Jon", "lastName": "Doe", "patientId": { "$binary": { "base64": "<ciphertext>", "subType": "06" } }, "address": "157 Electric Ave.", "patientRecord": { "ssn": { "$binary": { "base64": "<ciphertext>", "subType": "06" } }, "billing": { "$binary": { "base64": "<ciphertext>", "subType": "06" } } }, "medications": { "$binary": { "base64": "<ciphertext>", "subType": "06" } }, "__safeContent__": [ { "$binary": { "base64": "<ciphertext>", "subType": "00" } }, { "$binary": { "base64": "<ciphertext>", "subType": "00" } } ] }
警告
不要修改 __safeContent__ 字段
__safeContent__
字段对于 Queryable Encryption 至关重要。请勿修改此字段的内容。
提示
请参阅:完整代码
要查看插入加密文档的完整代码,请参阅 Queryable Encryption 示例应用程序存储库。
要查看插入加密文档的完整代码,请参阅 Queryable Encryption 示例应用程序存储库。
要查看插入加密文档的完整代码,请参阅 Queryable Encryption 示例应用程序存储库。
要查看插入加密文档的完整代码,请参阅 Queryable Encryption 示例应用程序存储库。
要查看插入加密文档的完整代码,请参阅 Queryable Encryption 示例应用程序存储库。
要查看插入加密文档的完整代码,请参阅 Queryable Encryption 示例应用程序存储库。
检索加密文档
检索在本指南的“插入具有加密字段的文档”步骤中插入的加密文档。
为了显示 Queryable Encryption 的功能,以下代码片段使用配置为自动 Queryable Encryption 的客户端以及未配置为自动 Queryable Encryption 的客户端来查询您的文档。
console.log("Finding a document with regular (non-encrypted) client."); console.log(unencryptedColl.findOne({ firstName: /Jon/ })); console.log( "Finding a document with encrypted client, searching on an encrypted field" ); console.log(encryptedColl.findOne({ "patientRecord.ssn": "987-65-4320" }));
Console.WriteLine("Finding a document with regular (non-encrypted) client."); var filter = Builders<BsonDocument>.Filter.Eq("firstName", "Jon"); var regularClientEncryptedCollection = regularClient.GetDatabase(encryptedCollectionNamespace.DatabaseNamespace.DatabaseName) .GetCollection<BsonDocument>(encryptedCollectionNamespace.CollectionName); var regularResult = regularClientEncryptedCollection.Find(filter).First(); Console.WriteLine($"\n{regularResult}\n"); Console.WriteLine("Finding a document with encrypted client, searching on an encrypted field"); var encryptedFieldFilter = Builders<BsonDocument>.Filter.Eq("patientRecord.ssn", "987-65-4320"); var secureResult = secureCollection.Find(encryptedFieldFilter).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{{"firstName", "Jon"}}).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{bson.E{"patientRecord.ssn", "987-65-4320"}}).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 = regularClient.getDatabase(encryptedDbName).getCollection(encryptedCollName).find(eq("firstName", "Jon")).first(); System.out.println(docRegular.toJson()); System.out.println("Finding a document with encrypted client, searching on an encrypted field"); Document docSecure = mongoClientSecure.getDatabase(encryptedDbName).getCollection(encryptedCollName).find(eq("patientRecord.ssn", "987-65-4320")).first(); System.out.println(docSecure.toJson());
console.log("Finding a document with regular (non-encrypted) client."); console.log(await unencryptedColl.findOne({ firstName: /Jon/ })); console.log( "Finding a document with encrypted client, searching on an encrypted field" ); console.log( await encryptedColl.findOne({ "patientRecord.ssn": "987-65-4320" }) );
print("Finding a document with regular (non-encrypted) client.") pprint.pprint( unencryptedClient[encrypted_db_name][encrypted_coll_name].find_one( {"firstName": "Jon"} ) ) print("Finding a document with encrypted client, searching on an encrypted field") pprint.pprint(encrypted_coll.find_one({"patientRecord.ssn": "987-65-4320"}))
上述代码片段的输出应如下所示:
Finding a document with regular (non-encrypted) client. { _id: new ObjectId("628eabeb37590e84ea742665"), firstName: 'Jon', lastName: 'Doe', patientId: new Binary(Buffer.from("0798810acc0f4f46c9a76883cee80fca12102e9ddcbcdae46a821fa108a8155a850f2d0919475b6531ada68973d436a199b537a05a98a708c36d2bfec4979d59cbe66878865ce19e392d3e4789d309bdacc336e32efcc851806ae0a41b355288c10d01e39147e1c40d919c41913a0c9d2d3fad0d0d1d2873c4fc82c6c22f27b517df5f3131b331b96ed16a7c5cf89e09082a2d898c2dcd73da91d08760ba74a70077b2d0fdbbe1eea75655a19fcc397812325ad40b102cbd16b8d36b22e11e3f93404f24a8ff68cfdec3c22b0e787cb30078a5227b2a", "hex"), 6), address: '157 Electric Ave.', patientRecord: { ssn: new Binary(Buffer.from("07e8b69630c32f4a00a542af768f8abcf50223edd812ff20b0ecb046ee1a9f5a0eef8d85d99cd26076411129942752516ee605c55aadce73f3d44d81ea6ddbbb8134b108a9deb40d8cab9cb4f08ef210ab0c9d2ea4347f9d235b861baf29751e60abcf059eb5c120305bd5ac05a4e07ac8ccfa6d37283f4cdbfeb7a8accb65b71857d486b5cf55e354d6a95e287d9e2dd65f3f9d9c4c9d0bdb1f26c4bd549d7be77db81796be293e08b2223bac67b212423c4e06568578b5bd7a3c33cedc1b291bcda0b27e005144d344563711a489f24b8e9b65bbb721d3a0e9d9b227a0cec0cbad", "hex"), 6), billing: new Binary(Buffer.from("06808ae69d4caa49cf90bb688f386f097f03f870a7b8fcebb1980c9ee5488b1f0f68558fc2163adcd92d00ea5f349f56ed34e7b391f54c48ed2760b4bde73022fc818dc7486a4e046b92ce9c82e00333c7779d9d6bb476713a20632b593b7de54812662cfc4d174d05451d3f4195514e12edba", "hex"), 6) }, medications: new Binary(Buffer.from("06665ec15d38254dc4aa16da856789d33404f27bfea53e0d2fa4deaff166989ab33f469644d89c29112d33b41dbe54ec2d89c43f3de52cdc5d454e8694046216f533614fa7b42b7c5406d6518f7ed8f9e3ce52fda6c8b2146d0f8cc51e21a3467183697e1735a9f60c18e173c1916101", "hex"), 6), __safeContent__: [ new Binary(Buffer.from("3044b134ad0f7c8a90dab1e05bb8b296a8ede540796bd7403ab47693cdba1b26", "hex"), 0), new Binary(Buffer.from("a22ddf9a5657cdd56bef72febbba44371899e6486962a1c07d682082c4e65712", "hex"), 0) ] } Finding a document with encrypted client, searching on an encrypted field { _id: new ObjectId("628eaca1dcf9b63e2f43162d"), firstName: 'Jon', lastName: 'Doe', patientId: 12345678, address: '157 Electric Ave.', patientRecord: { ssn: '987-65-4320', billing: { type: 'Visa', number: '4111111111111111' } }, medications: [ 'Atorvastatin', 'Levothyroxine' ], __safeContent__: [ new Binary(Buffer.from("fbdc6cfe3b4659693650bfc60baced27dcb42b793efe09da0ded54d60a9d5a1f", "hex"), 0), new Binary(Buffer.from("0f92ff92bf904a858ef6fd5b1e508187f523e791f51d8b64596461b38ebb1791", "hex"), 0) ] }
提示
请参阅:完整代码
要查看查找加密文档的完整代码,请参阅 Queryable Encryption 示例应用程序存储库。
要查看查找加密文档的完整代码,请参阅 Queryable Encryption 示例应用程序存储库。
要查看查找加密文档的完整代码,请参阅 Queryable Encryption 示例应用程序存储库。
要查看查找加密文档的完整代码,请参阅 Queryable Encryption 示例应用程序存储库。
要查看查找加密文档的完整代码,请参阅 Queryable Encryption 示例应用程序存储库。
要查看查找加密文档的完整代码,请参阅 Queryable Encryption 示例应用程序存储库。
了解详情
如需了解 Queryable Encryption 的工作原理,请参阅基础知识。
如需详细了解本指南中提到的主题,请参阅以下链接: