创建加密collection并插入文档
Overview
本指南向您介绍如何创建启用了Queryable Encryption的集合并插入具有加密字段的文档。
完成本指南中的步骤后,您应该能够创建加密集合并插入包含使用客户主密钥加密的字段的文档。
开始之前
在创建加密集合之前,创建启用了Queryable Encryption的应用程序。
如果使用显式加密,还必须事先为每个加密字段创建唯一的数据加密密钥。 有关详细信息,请参阅加密密钥和密钥保管库。
步骤
指定要加密的字段
要加密字段,请将其添加到加密模式中。 要启用对字段的查询,请添加 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# 版本使用单独的类作为 Realm 数据模型来表示文档结构。将以下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
类访问的加密助手方法创建加密collection。此方法自动为字段生成数据加密密钥并创建加密collection:
var createCollectionOptions = new CreateCollectionOptions<Patient> { EncryptedFields = encryptedFields }; clientEncryption.CreateEncryptedCollection(patientDatabase, encryptedCollectionName, createCollectionOptions, kmsProviderName, customerMasterKeyCredentials);
提示
数据库与数据库名称
创建集合的方法需要引用数据库对象,而不是数据库名称。
本教程的Go版本使用数据模型来表示文档结构。 将以下结构体添加到项目中以表示集合中的数据:
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
类访问的加密助手方法创建加密collection。此方法自动为字段生成数据加密密钥并创建加密collection:
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
使用 Node.js 驱动程序 v6.0 及更高版本时,必须从 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, )
提示
数据库与数据库名称
创建加密集合的方法需要引用数据库对象,而不是数据库名称。可以通过在客户端对象上使用方法来获取此引用。
有关更多信息,请参阅创建集合时启用Queryable Encryption 。
插入具有加密字段的文档
创建描述患者个人信息的示例文档。使用加密的客户端将其插入到 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)) }
本教程使用 POJO 作为数据模型来表示文档结构。 要将应用程序设立为使用 POJO,请添加以下代码:
CodecProvider pojoCodecProvider = PojoCodecProvider.builder().automatic(true).build(); CodecRegistry pojoCodecRegistry = fromRegistries(getDefaultCodecRegistry(), fromProviders(pojoCodecProvider));
要学习;了解有关Java POJO 的更多信息,请参阅 普通旧Java对象维基百科文章。
本教程使用以下 POJO:
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)
后续步骤
创建启用了Queryable Encryption的集合后,您可以查询加密字段。