使用 Azure 的自动客户端字段级加密
本页概述
概述
本指南将向您展示如何使用Azure Key Vault构建一个启用客户端字段级加密(CSFLE)的应用程序。
完成本指南中的步骤后,您应该拥有
在Azure Key Vault实例上托管的一个客户主密钥。
一个可工作的客户端应用程序,该应用程序使用您的客户主密钥插入具有加密字段的文档。
在开始之前
在完成并运行本指南中的代码之前,您需要设置您的开发环境,如下所示安装要求页面。
在本指南中,代码示例使用占位符文本。在运行示例之前,用您自己的值替换这些占位符。
例如
dek_id := "<Your Base64 DEK ID>"
您将用您的DEK ID替换引号之间的一切。
dek_id := "abc123"
从选择您的语言下拉菜单中选择您想查看代码示例的编程语言。
完整应用程序代码
要查看示例应用程序的完整代码,请在语言选择器中选择您的编程语言。
设置KMS
// 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.
重要
当使用以下命令在指南中构建或运行Golang代码时,请始终包含 cse
构建约束以启用CSFLE。go build
或 go run
,总是包含 cse
构建约束以启用CSFLE。以下shell命令示例显示了包含构建约束的方法:
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.
在Azure中注册您的应用程序
登录到 Azure.
在Azure Active Directory中注册您的应用程序
在Azure Active Directory上注册应用程序,请遵循微软的官方使用Microsoft身份平台注册应用程序快速入门。
重要
记录您的凭证
确保记录以下凭证
租户ID
客户端ID
客户端密钥
您将需要它们来在本教程的后面构建您的
kmsProviders
对象。重要
记录您的凭证
确保记录以下凭证
租户ID
客户端ID
客户端密钥
您将需要它们来在本教程的后面构建您的
kmsProviders
对象。重要
记录您的凭证
确保记录以下凭证
租户ID
客户端ID
客户端密钥
除非您在Azure虚拟机上运行客户端,否则您将需要这些凭证来在本教程的后面构建您的
kmsProviders
对象。重要
记录您的凭证
确保记录以下凭证
租户ID
客户端ID
客户端密钥
您将需要它们来在本教程的后面构建您的
kmsProviders
对象。重要
记录您的凭证
确保记录以下凭证
租户ID
客户端ID
客户端密钥
您将需要它们来在本教程的后面构建您的
kmsProviders
对象。
创建客户主密钥
创建您的Azure密钥保管库和客户主密钥
要创建新的Azure密钥保管库实例和客户主密钥,请遵循微软的官方使用Azure门户设置和检索Azure密钥保管库中的密钥快速入门。
注意
客户主密钥应该具有2048位或4096位的RSA密钥大小。
重要
记录您的凭证
确保记录以下凭证
密钥名称
密钥标识符(在本指南的后面称为
keyVaultEndpoint
)密钥版本
您将需要它们来在本教程的后面构建您的
dataKeyOpts
对象。授权权限
创建应用程序
在您的密钥保管库集合上创建唯一索引
在您的 encryption.__keyVault
命名空间中的 keyAltNames
字段上创建唯一索引。
选择与您偏好的 MongoDB 驱动程序对应的选项卡
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}}, )
创建新的数据加密密钥
添加您的 Azure 密钥保管库凭据
将服务账户凭据添加到您的 CSFLE 启用的客户端代码中。
var kmsProviders = new Dictionary<string, IReadOnlyDictionary<string, object>>(); var provider = "azure"; var azureKmsOptions = new Dictionary<string, object> { { "tenantId", "<Your Azure Tenant ID>" }, { "clientId", "<Your Azure Client ID>" }, { "clientSecret", "<Your Azure Client Secret>" }, }; 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); 提示
Azure 虚拟机托管标识
如果您的客户端运行在 Azure 虚拟机 (VM) 上,您可以允许 VM 使用其托管标识来对密钥保管库进行身份验证。
要允许 Azure VM 自动提供您的凭据,请分配一个空映射,而不是包含您的 Azure 凭据的映射,如下所示
String kmsProvider = "azure"; Map<String, Map<String, Object>> kmsProviders = new HashMap<String, Map<String, Object>>(); Map<String, Object> providerDetails = new HashMap<>(); 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 和区域。
kmsProviders.Add(provider, azureKmsOptions); var dataKeyOptions = new DataKeyOptions( masterKey: new BsonDocument { { "keyName", "<Your Azure Key Name>" }, { "keyVaultEndpoint", "<Your Azure Key Vault Endpoint>" }, }); 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>", } 生成您的数据加密密钥
使用本教程第一步中声明的变量生成您的数据加密密钥。
var clientEncryptionOptions = new ClientEncryptionOptions( keyVaultClient: keyVaultClient, keyVaultNamespace: keyVaultNamespace, kmsProviders: kmsProviders ); var clientEncryption = new ClientEncryption(clientEncryptionOptions); 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(). SetMasterKey(masterKey) 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().masterKey(masterKeyProperties)); 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, { masterKey: masterKey, }); console.log("DataKeyId [base64]: ", key.toString("base64")); await keyVaultClient.close(); await client.close(); 注意
导入 ClientEncryption
当使用 Node.js 驱动程序 v6.0 及更高版本时,您必须从
mongodb
中导入ClientEncryption
。对于更早的驱动程序版本,从
mongodb-client-encryption
中导入ClientEncryption
。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(provider, master_key) base_64_data_key_id = base64.b64encode(data_key_id) print("DataKeyId [base64]: ", base_64_data_key_id)
提示
了解更多
要查看一个图示,展示您的客户端应用程序如何在使用 Azure Key Vault 时创建数据加密密钥,请参阅架构。
要了解更多关于使用托管在 Azure Key Vault 中的客户主密钥加密的数据加密密钥的选项,请参阅kmsProviders 对象和dataKeyOpts 对象。
提示
参阅:完整代码
要查看创建数据加密密钥的完整代码,请参阅我们的 Github 仓库
要查看创建数据加密密钥的完整代码,请参阅我们的 Github 仓库。
要查看生成数据加密密钥的完整代码,请参阅我们的Github仓库。
要查看生成数据加密密钥的完整代码,请参阅我们的Github仓库。
要查看生成数据加密密钥的完整代码,请参阅我们的Github仓库。
配置MongoClient
提示
按照本教程中的剩余步骤在单独的文件中操作,不要使用上一步骤创建的文件。
要查看此文件的完整代码,请参阅我们的GitHub仓库
要查看此文件的完整代码,请参阅我们的GitHub仓库。
查看此文件的完整代码,请参阅我们的 Github 仓库。
查看此文件的完整代码,请参阅我们的 Github 仓库。
查看此文件的完整代码,请参阅我们的 Github 仓库。
指定密钥保管库集合命名空间
指定
encryption.__keyVault
作为密钥保管库集合命名空间。var keyVaultNamespace = CollectionNamespace.FromFullName("encryption.__keyVault"); keyVaultNamespace := "encryption.__keyVault" String keyVaultNamespace = "encryption.__keyVault"; const keyVaultNamespace = "encryption.__keyVault"; key_vault_namespace = "encryption.__keyVault" 指定您的 Azure 凭据
指定
azure
KMS 提供商和您的 Azure 凭据var kmsProviders = new Dictionary<string, IReadOnlyDictionary<string, object>>(); var 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); 提示
Azure 虚拟机托管标识
如果您的客户端运行在 Azure 虚拟机 (VM) 上,您可以允许 VM 使用其托管标识来对密钥保管库进行身份验证。
要允许 Azure VM 自动提供您的凭据,请分配一个空映射,而不是包含您的 Azure 凭据的映射,如下所示
String kmsProvider = "azure"; Map<String, Map<String, Object>> kmsProviders = new HashMap<String, Map<String, Object>>(); Map<String, Object> providerDetails = new HashMap<>(); kmsProviders.put(kmsProvider, providerDetails); const kmsProviders = { azure: { tenantId: "<Your Tenant ID>", clientId: "<Your Client ID>", clientSecret: "<Your Client Secret>", }, }; provider = "azure" kms_providers = { "azure": { "tenantId": "<Azure account organization>", "clientId": "<Azure client ID>", "clientSecret": "<Azure client secret>", } } 为您的集合创建加密方案
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} 指定自动加密共享库的位置
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>" } 创建MongoClient
使用前一步骤中声明的变量创建具有以下自动加密设置的MongoDB客户端对象
MongoClientSettings.Extensions.AddAutoEncryption(); // .NET/C# Driver v3.0 or later only 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); 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)
插入具有加密字段的文档
使用您的CSFLE启用MongoClient
实例,使用以下代码片段将具有加密字段的文档插入到medicalRecords.patients
命名空间
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) }
注意
而不是创建原始BSON文档,您可以直接将带有bson
标记的结构传递给驱动程序进行编码。
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", )
当您插入一个文档时,您的CSFLE启用客户端会加密文档的字段,使其看起来像以下这样
{ "_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" } } }
提示
参阅:完整代码
要查看插入具有加密字段的文档的完整代码,请参阅我们的GitHub仓库
要查看插入具有加密字段的文档的完整代码,请参阅我们的Github仓库。
要查看插入具有加密字段的文档的完整代码,请参阅我们的Github仓库。
要查看插入具有加密字段的文档的完整代码,请参阅我们的Github仓库。
要查看插入带有加密字段的文档的完整代码,请参阅我们的Github 代码库。
检索带有加密字段的文档
检索您在本指南的插入带有加密字段的文档步骤中插入的带有加密字段的文档。
为了展示CSFLE的功能,以下代码片段查询了一个配置为自动CSFLE的客户端以及未配置为自动CSFLE的客户端的文档。
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"); var ssnFilter = Builders<BsonDocument>.Filter.Eq("name", "Jon Doe"); 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") var resultSecure bson.M err = secureClient.Database(dbName).Collection(collName).FindOne(context.TODO(), bson.D{{"name", "Jon Doe"}}).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"); Document docSecure = mongoClientSecure.getDatabase(recordsDb).getCollection(recordsColl).find(eq("name", "Jon Doe")).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"); console.log( await secureClient.db(db).collection(coll).findOne({ name: /Jon/ }) );
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") pprint.pprint(secureClient.medicalRecords.patients.find_one({"name": "Jon Doe"}))
上述代码片段的输出应如下所示
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 { _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' } }
提示
参阅:完整代码
要查看带有加密字段的文档的完整代码,请参阅我们的Github仓库
要查看带有加密字段的文档的完整代码,请参阅我们的Github仓库。
要查看带有加密字段的文档的完整代码,请参阅我们的Github仓库。
要查看带有加密字段的文档的完整代码,请参阅我们的Github 仓库。
要查看带有加密字段的文档的完整代码,请参阅我们的Github 仓库。
了解更多
要了解CSFLE的工作原理,请参阅基础。
要了解本指南中提到的主题的更多内容,请参阅以下链接
在参考页面上了解CSFLE组件的更多信息。
在加密密钥和密钥保管库页面上了解客户主密钥和数据加密密钥的工作原理。
在KMS 提供商页面上查看KMS提供商如何管理您的CSFLE密钥。