通过 KMIP 使用客户端字段级自动加密
在此页面上
Overview
This guide shows you how to build a Client-Side Field Level Encryption (CSFLE)-enabled application using a Key Management Interoperability Protocol (KMIP)-compliant key provider.
在完成本指南中的步骤后,您应该具有:
A Customer Master Key hosted on a KMIP-compliant key provider.
正常工作的客户端应用程序;可以使用客户主密钥插入具有加密字段的文档。
开始之前
要完成并运行本指南中的代码,您需要按照安装要求页面中的步骤来设置开发环境。
在本指南中,代码示例使用占位符文本。在运行示例之前,请用您自己的值替换这些占位符。
例如:
dek_id := "<Your Base64 DEK ID>"
您可以将引号之间的内容替换为您的 DEK ID。
dek_id := "abc123"
从页面右侧的 Select your language 下拉菜单中选择您想要查看其代码示例的编程语言。
提示
请参阅:完整应用程序
要查看本教程的完整可运行应用程序代码,请访问以下链接:
设置 KMS
注意
mongod
reads the KMIP configuration at startup. By default, the
server uses KMIP protocol version 1.2.
To connect to a version 1.0 or 1.1 KMIP server, use the
useLegacyProtocol
setting.
// 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.
重要
使用 go build
或 go run
构建或运行本指南中的Go代码时,请始终包含 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.
Configure your KMIP-compliant key provider
To connect a MongoDB driver client to your KMIP-compliant key provider, you must configure your KMIP-compliant key provider such that it accepts your client's TLS certificate.
Consult the documentation for your KMIP-compliant key provider for information on how to accept your client certificate.
Specify your Certificates
Your client must connect to your KMIP-compliant key provider through TLS and present a client certificate that your KMIP-compliant key provider accepts:
var tlsOptions = new Dictionary<string, SslSettings>(); var sslSettings = new SslSettings(); var clientCertificate = new X509Certificate2("<path to your pkcs12 client certificate file>"); sslSettings.ClientCertificates = new List<X509Certificate>() { clientCertificate, }; tlsOptions.Add(provider, sslSettings);
重要
Your client certificate must be in pkcs12 format. You can convert your certificate using your certificate using OpenSSL with the following command:
openssl pkcs12 -export -out "<new pkcs12 certificate>" -in "<certificate to convert>" \ -name "<new certificate name>" -password "<new certificate password>"
tlsConfig := make(map[string]*tls.Config) tlsOpts := map[string]interface{}{ "tlsCertificateKeyFile": "<path to your client certificate file>", "tlsCAFile": "<path to file containing your Certificate Authority certificate>", } kmipConfig, err := options.BuildTLSConfig(tlsOpts) tlsConfig["kmip"] = kmipConfig
重要
You must use certificates with ECDSA keys when using the Go driver.
Specify the following Java system properties to configure your client's TLS connection:
-Djavax.net.ssl.keyStoreType=pkcs12 -Djavax.net.ssl.keyStore=<path to pkcs12 KeyStore containing your client certificate> -Djavax.net.ssl.keyStorePassword=<KeyStore password>
注意
Configure Client With SSLContext
If you would rather configure your client application using an SSL context, use the kmsProviderSslContextMap method.
const tlsOptions = { kmip: { tlsCAFile: "<path to file containing your Certificate Authority certificate>", tlsCertificateKeyFile: "<path to your client certificate file>", }, };
tls_options = { "kmip": { "tlsCAFile": "<path to file containing your Certificate Authority certificate>", "tlsCertificateKeyFile": "<path to your client certificate file>", } }
创建应用程序
Select the tab that corresponds to the MongoDB driver you are using in your application to see relevant code samples.
Create a Unique Index on Your Key Vault Collection
在 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}}, )
创建数据加密密钥
Add your Endpoint
Specify the URI endpoint of your KMIP-compliant key provider:
var kmsProviders = new Dictionary<string, IReadOnlyDictionary<string, object>>(); var provider = "kmip"; var kmipKmsOptions = new Dictionary<string, object> { { "endpoint", "<endpoint for your KMIP-compliant key provider>" }, }; kmsProviders.Add(provider, kmipKmsOptions);
provider := "kmip" kmsProviders := map[string]map[string]interface{}{ provider: { "endpoint": "<endpoint for your KMIP-compliant key provider>", }, }
String kmsProvider = "kmip"; Map<String, Map<String, Object>> kmsProviders = new HashMap<String, Map<String, Object>>(); Map<String, Object> providerDetails = new HashMap<>(); providerDetails.put("endpoint", "<endpoint for your KMIP-compliant key provider>"); kmsProviders.put(kmsProvider, providerDetails);
const provider = "kmip"; const kmsProviders = { kmip: { endpoint: "<endpoint for your KMIP-compliant key provider>", }, };
provider = "kmip" kms_providers = { provider: {"endpoint": "<endpoint for your KMIP-compliant key provider>"} }
添加您的密钥信息
The following code prompts your KMIP-compliant key provider to automatically generate a Customer Master Key:
var dataKeyOptions = new DataKeyOptions( masterKey: new BsonDocument { } // an empty key object prompts your KMIP-compliant key provider to generate a new Customer Master Key );
masterKey := map[string]interface{}{} // an empty key object prompts your KMIP-compliant key provider to generate a new Customer Master Key
BsonDocument masterKeyProperties = new BsonDocument(); // an empty key object prompts your KMIP-compliant key provider to generate a new Customer Master Key
const masterKey = {}; // an empty key object prompts your KMIP-compliant key provider to generate a new Customer Master Key
master_key = ( {} ) # an empty key object prompts your KMIP-compliant key provider to generate a new Customer Master Key
生成数据加密密钥
使用本教程的步骤 1 中声明的变量,生成数据加密密钥。
var clientEncryptionOptions = new ClientEncryptionOptions( keyVaultClient: keyVaultClient, keyVaultNamespace: keyVaultNamespace, kmsProviders: kmsProviders, tlsOptions: tlsOptions ); 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).SetTLSConfig(tlsConfig) 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, { useNewUrlParser: true, useUnifiedTopology: true, }); await client.connect(); const encryption = new ClientEncryption(client, { keyVaultNamespace, kmsProviders, tlsOptions, }); const key = await encryption.createDataKey(provider, { masterKey: masterKey, }); console.log("DataKeyId [base64]: ", key.toString("base64")); await keyVaultClient.close(); await client.close();
注意
Import 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), kms_tls_options=tls_options, ) 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)
提示
请参阅:完整代码
要查看制作数据加密密钥的完整代码,请参阅我们的 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"
Specify your KMIP Endpoint
Specify kmip
in your kmsProviders
object and enter
the URI endpoint of your KMIP-compliant key provider:
var kmsProviders = new Dictionary<string, IReadOnlyDictionary<string, object>>(); var provider = "kmip"; var kmipKmsOptions = new Dictionary<string, object> { { "endpoint", "<endpoint for your KMIP-compliant key provider>" }, }; kmsProviders.Add(provider, kmipKmsOptions);
provider := "kmip" kmsProviders := map[string]map[string]interface{}{ provider: { "endpoint": "<endpoint for your KMIP-compliant key provider>", }, }
String kmsProvider = "kmip"; Map<String, Map<String, Object>> kmsProviders = new HashMap<String, Map<String, Object>>(); Map<String, Object> providerDetails = new HashMap<>(); providerDetails.put("endpoint", "<endpoint for your KMIP-compliant key provider>"); kmsProviders.put(kmsProvider, providerDetails);
const provider = "kmip"; const kmsProviders = { kmip: { endpoint: "<endpoint for your KMIP-compliant key provider>", }, };
provider = "kmip" kms_providers = { provider: {"endpoint": "<endpoint for your KMIP-compliant key provider>"} }
为集合创建加密模式
Create an encryption schema that specifies how your client application encrypts your documents' fields:
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}
提示
Further Reading on Schemas
To view an in-depth description of how to construct the schema you use in this step, see the 加密模式 guide.
To view a list of all supported encryption rules for your encryption schemas, see the CSFLE 加密模式 guide.
指定自动加密共享库位置
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 客户端对象,这些设置使用前面步骤中声明的变量:
var clientSettings = MongoClientSettings.FromConnectionString(connectionString); var autoEncryptionOptions = new AutoEncryptionOptions( keyVaultNamespace: keyVaultNamespace, kmsProviders: kmsProviders, schemaMap: schemaMap, extraOptions: extraOptions, tlsOptions: tlsOptions ); clientSettings.AutoEncryptionOptions = autoEncryptionOptions; var secureClient = new MongoClient(clientSettings);
autoEncryptionOpts := options.AutoEncryption(). SetKmsProviders(kmsProviders). SetKeyVaultNamespace(keyVaultNamespace). SetSchemaMap(schemaMap). SetExtraOptions(extraOptions).SetTLSConfig(tlsConfig) 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, { useNewUrlParser: true, useUnifiedTopology: true, autoEncryption: { keyVaultNamespace, kmsProviders, schemaMap: patientSchema, extraOptions: extraOptions, tlsOptions, }, });
fle_opts = AutoEncryptionOpts( kms_providers, key_vault_namespace, schema_map=patient_schema, kms_tls_options=tls_options, **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, searching on an encrypted field"); var ssnFilter = Builders<BsonDocument>.Filter.Eq("ssn", 145014000); var secureResult = secureCollection.Find(ssnFilter).Limit(1).First(); Console.WriteLine($"\n{secureResult}\n");
fmt.Println("Finding a document with regular (non-encrypted) client.") var resultRegular bson.M err = regularClient.Database(dbName).Collection(collName).FindOne(context.TODO(), bson.D{{"name", "Jon Doe"}}).Decode(&resultRegular) if err != nil { panic(err) } outputRegular, err := json.MarshalIndent(resultRegular, "", " ") if err != nil { panic(err) } fmt.Printf("%s\n", outputRegular) fmt.Println("Finding a document with encrypted client, searching on an encrypted field") var resultSecure bson.M err = secureClient.Database(dbName).Collection(collName).FindOne(context.TODO(), bson.D{{"ssn", "241014209"}}).Decode(&resultSecure) if err != nil { panic(err) } outputSecure, err := json.MarshalIndent(resultSecure, "", " ") if err != nil { panic(err) } fmt.Printf("%s\n", outputSecure)
System.out.println("Finding a document with regular (non-encrypted) client."); Document docRegular = mongoClientRegular.getDatabase(recordsDb).getCollection(recordsColl).find(eq("name", "Jon Doe")).first(); System.out.println(docRegular.toJson()); System.out.println("Finding a document with encrypted client, searching on an encrypted field"); Document docSecure = mongoClientSecure.getDatabase(recordsDb).getCollection(recordsColl).find(eq("ssn", 241014209)).first(); System.out.println(docSecure.toJson());
console.log("Finding a document with regular (non-encrypted) client."); console.log( await regularClient.db(db).collection(coll).findOne({ name: /Jon/ }) ); console.log( "Finding a document with encrypted client, searching on an encrypted field" ); console.log( await secureClient.db(db).collection(coll).findOne({ ssn: "241014209" }) );
print("Finding a document with regular (non-encrypted) client.") result = regularClient.medicalRecords.patients.find_one({"name": "Jon Doe"}) pprint.pprint(result) print("Finding a document with encrypted client, searching on an encrypted field") pprint.pprint(secureClient.medicalRecords.patients.find_one({"ssn": 241014209}))
上述代码片段的输出应如下所示:
Finding a document with regular (non-encrypted) client. { _id: new ObjectId("629a452e0861b3130887103a"), name: 'Jon Doe', ssn: new Binary(Buffer.from("0217482732d8014cdd9ffdd6e2966e5e7910c20697e5f4fa95710aafc9153f0a3dc769c8a132a604b468732ff1f4d8349ded3244b59cbfb41444a210f28b21ea1b6c737508d9d30e8baa30c1d8070c4d5e26", "hex"), 6), bloodType: new Binary(Buffer.from("0217482732d8014cdd9ffdd6e2966e5e79022e238536dfd8caadb4d7751ac940e0f195addd7e5c67b61022d02faa90283ab69e02303c7e4001d1996128428bf037dea8bbf59fbb20c583cbcff2bf3e2519b4", "hex"), 6), 'key-id': 'demo-data-key', medicalRecords: new Binary(Buffer.from("0217482732d8014cdd9ffdd6e2966e5e790405163a3207cff175455106f57eef14e5610c49a99bcbd14a7db9c5284e45e3ee30c149354015f941440bf54725d6492fb3b8704bc7c411cff6c868e4e13c58233c3d5ed9593eca4e4d027d76d3705b6d1f3b3c9e2ceee195fd944b553eb27eee69e5e67c338f146f8445995664980bf0", "hex"), 6), insurance: { policyNumber: new Binary(Buffer.from("0217482732d8014cdd9ffdd6e2966e5e79108decd85c05be3fec099e015f9d26d9234605dc959cc1a19b63072f7ffda99db38c7b487de0572a03b2139ac3ee163bcc40c8508f366ce92a5dd36e38b3c742f7", "hex"), 6), provider: 'MaestCare' } } Finding a document with encrypted client, searching on an encrypted field { _id: new ObjectId("629a452e0861b3130887103a"), name: 'Jon Doe', ssn: 241014209, bloodType: 'AB+', 'key-id': 'demo-data-key', medicalRecords: [ { weight: 180, bloodPressure: '120/80' } ], insurance: { policyNumber: 123142, provider: 'MaestCare' } }
提示
请参阅:完整代码
要查看用于插入带加密字段的文档的完整代码,请访问我们的 Github 存储库
要查看用于插入带加密字段的文档的完整代码,请访问我们的 Github 存储库。
要查看用于插入带加密字段的文档的完整代码,请访问我们的 Github 存储库。
要查看用于插入带加密字段的文档的完整代码,请访问我们的 Github 存储库。
要查看用于插入带加密字段的文档的完整代码,请访问我们的 Github 存储库。
了解详情
如需了解 CSFLE 的工作原理,请参阅基础知识。
如需详细了解本指南中提到的主题,请参阅以下链接:
有关 CSFLE 组件的更多信息,请参阅参考页面。
访问密钥和密钥保管库页面,了解客户主密钥和数据加密密钥的工作原理。
在 CSFLE KMS 提供者页面上了解 KMS 提供者如何管理您的 CSFLE 密钥。