创建加密集合并插入文档
概述
本指南展示了如何创建一个启用可查询加密的集合,并插入一个具有加密字段的文档。
完成本指南中的步骤后,您应该能够创建一个加密集合,并使用您的客户主密钥加密的字段插入文档。
开始之前
在创建加密集合之前,请先创建您的可查询加密应用。
如果您正在使用显式加密,您还必须在事先为每个加密字段创建一个唯一的数据加密密钥。有关更多信息,请参阅加密密钥和密钥保管库。
步骤
指定要加密的字段
要加密一个字段,请将其添加到加密模式。要启用字段上的查询,请添加queries
属性。您可以通过等值查询或范围查询启用可查询的字段。以下步骤演示了如何根据每种查询类型指定要加密的字段。
指定等值查询的字段
要启用字段上的等值查询,请将字段添加到加密模式,并设置
queryType
为"equality"
。以下代码示例加密了ssn
和billing
字段,但只有ssn
字段是可查询的const encryptedFieldsMap = { encryptedFields: { fields: [ { path: "patientRecord.ssn", bsonType: "string", queries: { queryType: "equality" }, }, { path: "patientRecord.billing", bsonType: "object", }, ], }, }; var encryptedFields = new BsonDocument { { "fields", new BsonArray { new BsonDocument { { "keyId", BsonNull.Value }, { "path", "patientRecord.ssn" }, { "bsonType", "string" }, { "queries", new BsonDocument("queryType", "equality") } }, new BsonDocument { { "keyId", BsonNull.Value }, { "path", "patientRecord.billing" }, { "bsonType", "object" } } } } }; encryptedFieldsMap := bson.M{ "fields": []bson.M{ bson.M{ "keyId": nil, "path": "patientRecord.ssn", "bsonType": "string", "queries": []bson.M{ { "queryType": "equality", }, }, }, bson.M{ "keyId": nil, "path": "patientRecord.billing", "bsonType": "object", }, }, } BsonDocument encryptedFieldsMap = new BsonDocument().append("fields", new BsonArray(Arrays.asList( new BsonDocument() .append("keyId", new BsonNull()) .append("path", new BsonString("patientRecord.ssn")) .append("bsonType", new BsonString("string")) .append("queries", new BsonDocument() .append("queryType", new BsonString("equality"))), new BsonDocument() .append("keyId", new BsonNull()) .append("path", new BsonString("patientRecord.billing")) .append("bsonType", new BsonString("object"))))); const encryptedFieldsMap = { encryptedFields: { fields: [ { path: "patientRecord.ssn", bsonType: "string", queries: { queryType: "equality" }, }, { path: "patientRecord.billing", bsonType: "object", }, ], }, }; encrypted_fields_map = { "fields": [ { "path": "patientRecord.ssn", "bsonType": "string", "queries": [{"queryType": "equality"}] }, { "path": "patientRecord.billing", "bsonType": "object", } ] } 指定范围查询的字段
要启用字段上的范围查询,请将字段添加到加密模式,并设置
queryType
为"range"
。以下示例将billAmount
字段添加到前面步骤中创建的加密模式,并启用对其的范围查询const encryptedFieldsMap = { encryptedFields: { fields: [ { path: "patientRecord.ssn", bsonType: "string", queries: { queryType: "equality" }, }, { path: "patientRecord.billing", bsonType: "object", }, { path: "patientRecord.billAmount", bsonType: "int", queries: { queryType: "range", sparsity: 1, trimFactor: 4, min: 100, max: 2000, }, }, ], }, }; var encryptedFields = new BsonDocument { { "fields", new BsonArray { new BsonDocument { { "keyId", BsonNull.Value }, { "path", "patientRecord.ssn" }, { "bsonType", "string" }, { "queries", new BsonDocument("queryType", "equality") } }, new BsonDocument { { "keyId", BsonNull.Value }, { "path", "patientRecord.billing" }, { "bsonType", "object" } }, new BsonDocument { { "keyId", BsonNull.Value }, { "path", "patientRecord.billAmount" }, { "bsonType", "int" }, { "queries", new BsonDocument { { "queryType", "range" }, { "sparsity", 1 }, { "min", 100 }, { "max", 2000 }, { "trimFactor", 4 } } }, } } } }; encryptedFieldsMap := bson.M{ "fields": []bson.M{ bson.M{ "keyId": nil, "path": "patientRecord.ssn", "bsonType": "string", "queries": []bson.M{ { "queryType": "equality", }, }, }, bson.M{ "keyId": nil, "path": "patientRecord.billing", "bsonType": "object", }, bson.M{ "keyId": nil, "path": "patientRecord.billAmount", "bsonType": "int", "queries": []bson.M{ { "queryType": "range", "sparsity": 1, "min": 100, "max": 2000, "trimFactor": 4, }, }, }, }, } BsonDocument encryptedFieldsMap = new BsonDocument().append("fields", new BsonArray(Arrays.asList( new BsonDocument() .append("keyId", new BsonNull()) .append("path", new BsonString("patientRecord.ssn")) .append("bsonType", new BsonString("string")) .append("queries", new BsonDocument() .append("queryType", new BsonString("equality"))), new BsonDocument() .append("keyId", new BsonNull()) .append("path", new BsonString("patientRecord.billing")) .append("bsonType", new BsonString("object")), new BsonDocument() .append("keyId", new BsonNull()) .append("path", new BsonString("patientRecord.billAmount")) .append("bsonType", new BsonString("int")) .append("queries", new BsonDocument() .append("queryType", new BsonString("range")) .append("sparsity", new BsonInt32(1)) .append("trimFactor", new BsonInt32(4)) .append("min", new BsonInt32(100)) .append("max", new BsonInt32(2000)) )))); const encryptedFieldsMap = { encryptedFields: { fields: [ { path: "patientRecord.ssn", bsonType: "string", queries: { queryType: "equality" }, }, { path: "patientRecord.billing", bsonType: "object", }, { path: "patientRecord.billAmount", bsonType: "int", queries: { queryType: "range", sparsity: 1, trimFactor: 4, min: 100, max: 2000, }, }, ], }, }; encrypted_fields_map = { "fields": [ { "path": "patientRecord.ssn", "bsonType": "string", "queries": [{"queryType": "equality"}] }, { "path": "patientRecord.billing", "bsonType": "object", }, { "path": "patientRecord.billAmount", "bsonType": "int", "queries": [{ "queryType": "range", "sparsity": 1, "min": 100, "max": 2000, "trimFactor": 4 }], }, ] }
有关这些步骤的扩展版本,请参阅 创建加密模式。
实例化 ClientEncryption
以访问加密辅助方法的 API
const clientEncryption = encryptedClient.getClientEncryption();
var clientEncryptionOptions = new ClientEncryptionOptions( keyVaultClient: keyVaultClient, keyVaultNamespace: keyVaultNamespace, kmsProviders: kmsProviderCredentials ); var clientEncryption = new ClientEncryption(clientEncryptionOptions);
opts := options.ClientEncryption(). SetKeyVaultNamespace(keyVaultNamespace). SetKmsProviders(kmsProviderCredentials) clientEncryption, err := mongo.NewClientEncryption(encryptedClient, opts) if err != nil { panic(fmt.Sprintf("Unable to create a ClientEncryption instance due to the following error: %s\n", err)) }
ClientEncryptionSettings clientEncryptionSettings = ClientEncryptionSettings.builder() .keyVaultMongoClientSettings(MongoClientSettings.builder() .applyConnectionString(new ConnectionString(uri)) .build()) .keyVaultNamespace(keyVaultNamespace) .kmsProviders(kmsProviderCredentials) .build(); ClientEncryption clientEncryption = ClientEncryptions.create(clientEncryptionSettings);
const clientEncryption = new ClientEncryption( encryptedClient, autoEncryptionOptions );
client_encryption = ClientEncryption( kms_providers=kms_provider_credentials, key_vault_namespace=key_vault_namespace, key_vault_client=encrypted_client, codec_options=CodecOptions(uuid_representation=STANDARD) )
创建集合
重要
显式创建您的集合,而不是通过插入操作隐式创建它。当您使用 createCollection()
创建集合时,MongoDB 会为加密字段创建索引。如果没有这个索引,对加密字段的查询可能会运行缓慢。
通过通过 ClientEncryption
类访问的加密辅助方法创建您的加密集合。此方法会自动生成加密字段的加密密钥并创建加密集合
await clientEncryption.createEncryptedCollection( encryptedDatabaseName, encryptedCollectionName, { provider: kmsProviderName, createCollectionOptions: encryptedFieldsMap, masterKey: customerMasterKeyCredentials, } );
本教程的 C# 版本使用单独的类作为数据模型来表示文档结构。将以下 Patient
、PatientRecord
和 PatientBilling
类添加到您的项目中
using MongoDB.Bson; using MongoDB.Bson.Serialization.Attributes; [ ]public class Patient { public ObjectId Id { get; set; } public string PatientName { get; set; } public PatientRecord PatientRecord { get; set; } }
public class PatientRecord { public string Ssn { get; set; } public PatientBilling Billing { get; set; } public int BillAmount { get; set; } }
public class PatientBilling { public string CardType { get; set; } public long CardNumber { get; set; } }
添加这些类后,使用通过 ClientEncryption
类访问的加密辅助方法创建您的加密集合。此方法会自动生成加密字段的加密密钥并创建加密集合
var createCollectionOptions = new CreateCollectionOptions<Patient> { EncryptedFields = encryptedFields }; clientEncryption.CreateEncryptedCollection(patientDatabase, encryptedCollectionName, createCollectionOptions, kmsProviderName, customerMasterKeyCredentials);
提示
数据库名称与数据库
创建集合的方法需要一个数据库 对象 的引用,而不是数据库 名称。
本教程的 Golang 版本使用数据模型来表示文档结构。将以下结构体添加到您的项目中,以表示集合中的数据
type PatientDocument struct { PatientName string `bson:"patientName"` PatientID int32 `bson:"patientId"` PatientRecord PatientRecord `bson:"patientRecord"` }
type PatientRecord struct { SSN string `bson:"ssn"` Billing PaymentInfo `bson:"billing"` BillAmount int `bson:"billAmount"` }
type PaymentInfo struct { Type string `bson:"type"` Number string `bson:"number"` }
添加这些类后,使用通过 ClientEncryption
类访问的加密辅助方法创建您的加密集合。此方法会自动生成加密字段的加密密钥并创建加密集合
createCollectionOptions := options.CreateCollection().SetEncryptedFields(encryptedFieldsMap) _, _, err = clientEncryption.CreateEncryptedCollection( context.TODO(), encryptedClient.Database(encryptedDatabaseName), encryptedCollectionName, createCollectionOptions, kmsProviderName, customerMasterKey, )
提示
数据库名称与数据库
创建加密集合的方法需要一个数据库 对象 的引用,而不是数据库 名称。您可以通过客户端对象上的方法获取此引用。
通过通过 ClientEncryption
类访问的加密辅助方法创建您的加密集合。此方法会自动生成加密字段的加密密钥并创建加密集合
CreateCollectionOptions createCollectionOptions = new CreateCollectionOptions().encryptedFields(encryptedFieldsMap); CreateEncryptedCollectionParams encryptedCollectionParams = new CreateEncryptedCollectionParams(kmsProviderName); encryptedCollectionParams.masterKey(customerMasterKeyCredentials); try { clientEncryption.createEncryptedCollection( encryptedClient.getDatabase(encryptedDatabaseName), encryptedCollectionName, createCollectionOptions, encryptedCollectionParams); }
提示
数据库名称与数据库
创建加密集合的方法需要一个数据库 对象 的引用,而不是数据库 名称。您可以通过客户端对象上的方法获取此引用。
注意
导入 ClientEncryption
当使用 v6.0 及以后的 Node.js 驱动程序时,您必须从 mongodb
导入 ClientEncryption
。
对于较早的驱动程序版本,从 mongodb-client-encryption
导入 ClientEncryption
。
通过通过 ClientEncryption
类访问的加密辅助方法创建您的加密集合。此方法会自动生成加密字段的加密密钥并创建加密集合
await clientEncryption.createEncryptedCollection( encryptedDatabase, encryptedCollectionName, { provider: kmsProviderName, createCollectionOptions: encryptedFieldsMap, masterKey: customerMasterKeyCredentials, } );
提示
数据库名称与数据库
创建加密集合的方法需要一个数据库 对象 的引用,而不是数据库 名称。
通过通过 ClientEncryption
类访问的加密辅助方法创建您的加密集合。此方法会自动生成加密字段的加密密钥并创建加密集合
client_encryption.create_encrypted_collection( encrypted_client[encrypted_database_name], encrypted_collection_name, encrypted_fields_map, kms_provider_name, customer_master_key_credentials, )
提示
数据库名称与数据库
创建加密集合的方法需要一个数据库 对象 的引用,而不是数据库 名称。您可以通过客户端对象上的方法获取此引用。
有关更多信息,请参阅 创建集合时启用可查询加密。
插入带加密字段的文档
创建一个描述病人个人信息的示例文档。使用加密客户端将其插入到patients
集合中,如下例所示
const patientDocument = { patientName: "Jon Doe", patientId: 12345678, patientRecord: { ssn: "987-65-4320", billing: { type: "Visa", number: "4111111111111111", }, billAmount: 1500, }, }; const encryptedCollection = encryptedClient .getDB(encryptedDatabaseName) .getCollection(encryptedCollectionName); const insertResult = await encryptedCollection.insertOne(patientDocument);
创建一个描述病人个人信息的示例文档。使用加密客户端将其插入到patients
集合中,如下例所示
var patient = new Patient { PatientName = "Jon Doe", Id = new ObjectId(), PatientRecord = new PatientRecord { Ssn = "987-65-4320", Billing = new PatientBilling { CardType = "Visa", CardNumber = 4111111111111111, }, BillAmount = 1500 } }; var encryptedCollection = encryptedClient.GetDatabase(encryptedDatabaseName). GetCollection<Patient>(encryptedCollectionName); encryptedCollection.InsertOne(patient);
创建一个描述病人个人信息的示例文档。使用加密客户端将其插入到patients
集合中,如下例所示
patientDocument := &PatientDocument{ PatientName: "Jon Doe", PatientID: 12345678, PatientRecord: PatientRecord{ SSN: "987-65-4320", Billing: PaymentInfo{ Type: "Visa", Number: "4111111111111111", }, BillAmount: 1500, }, } coll := encryptedClient.Database(encryptedDatabaseName).Collection(encryptedCollectionName) _, err = coll.InsertOne(context.TODO(), patientDocument) if err != nil { panic(fmt.Sprintf("Unable to insert the patientDocument: %s", err)) }
本教程使用POJOs作为数据模型来表示文档结构。要将您的应用程序配置为使用POJOs,请添加以下代码
CodecProvider pojoCodecProvider = PojoCodecProvider.builder().automatic(true).build(); CodecRegistry pojoCodecRegistry = fromRegistries(getDefaultCodecRegistry(), fromProviders(pojoCodecProvider));
有关Java POJOs的更多信息,请参阅普通Java对象维基百科文章.
本教程使用以下POJOs
Patient
PatientRecord
PatientBilling
将这些POJO类添加到您的应用程序中。然后,创建一个描述病人个人信息的Patient
实例。使用加密客户端将其插入到patients
集合中,如下例所示
MongoDatabase encryptedDb = encryptedClient.getDatabase(encryptedDatabaseName).withCodecRegistry(pojoCodecRegistry); MongoCollection<Patient> collection = encryptedDb.getCollection(encryptedCollectionName, Patient.class); PatientBilling patientBilling = new PatientBilling("Visa", "4111111111111111"); PatientRecord patientRecord = new PatientRecord("987-65-4320", patientBilling, 1500); Patient patientDocument = new Patient("Jon Doe", patientRecord); InsertOneResult result = collection.insertOne(patientDocument);
创建一个描述病人个人信息的示例文档。使用加密客户端将其插入到patients
集合中,如下例所示
const patientDocument = { patientName: "Jon Doe", patientId: 12345678, patientRecord: { ssn: "987-65-4320", billing: { type: "Visa", number: "4111111111111111", }, billAmount: 1500, }, }; const encryptedCollection = encryptedClient .db(encryptedDatabaseName) .collection(encryptedCollectionName); const result = await encryptedCollection.insertOne(patientDocument);
创建一个描述病人个人信息的示例文档。使用加密客户端将其插入到patients
集合中,如下例所示
patient_document = { "patientName": "Jon Doe", "patientId": 12345678, "patientRecord": { "ssn": "987-65-4320", "billing": { "type": "Visa", "number": "4111111111111111", }, "billAmount": 1500, }, } encrypted_collection = encrypted_client[encrypted_database_name][encrypted_collection_name] result = encrypted_collection.insert_one(patient_document)
下一步
创建一个启用可查询加密的集合后,您可以查询加密字段。