Docs 菜单
Docs 主页
/
MongoDB Manual
/ / / / / /

创建加密collection并插入文档

在此页面上

  • Overview
  • 开始之前
  • 步骤
  • 后续步骤

本指南向您介绍如何创建启用了 Queryable Encryption 的集合并插入具有加密字段的文档。

完成本指南中的步骤后,您应该能够创建加密集合并插入包含使用客户主密钥加密的字段的文档。

在创建加密集合之前,创建启用了 Queryable Encryption 的应用程序

如果使用显式加密,还必须事先为每个加密字段创建唯一的数据加密密钥。有关详细信息,请参阅加密密钥和密钥保管库。

1

要加密字段,请将其添加到加密模式中。 要启用对字段的查询,请添加 queries属性。

创建加密模式,如下所示。此代码示例会加密ssnbilling字段,但只有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",
}
]
}

有关此步骤的扩展版本,请参阅创建加密模式。

2
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)
)
3

重要

显式创建集合,而不是使用插入操作隐式创建集合。在您使用 createCollection() 创建集合时,MongoDB 在加密字段上创建索引。如果没有该索引,对加密字段的查询可能运行缓慢。

使用可通过ClientEncryption类访问的加密助手方法创建加密集合。此方法自动为加密字段生成数据加密密钥并创建加密集合:

await clientEncryption.createEncryptedCollection(
encryptedDatabaseName,
encryptedCollectionName,
{
provider: kmsProviderName,
createCollectionOptions: encryptedFieldsMap,
masterKey: customerMasterKeyCredentials,
}
);

本教程的 C# 版本使用单独的类作为 Realm 数据模型来表示文档结构。将以下PatientPatientRecordPatientBilling类添加到您的项目中:

using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
[BsonIgnoreExtraElements]
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 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"`
}
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。

4

创建描述患者个人信息的示例文档。使用加密的客户端将其插入到 patients 集合中,如以下示例所示:

const patientDocument = {
patientName: "Jon Doe",
patientId: 12345678,
patientRecord: {
ssn: "987-65-4320",
billing: {
type: "Visa",
number: "4111111111111111",
},
},
};
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
}
}
};
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",
},
},
}
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

您可以 在完整 Java 应用程序的模型包中查看这些类。

将这些 POJOPatient patients类添加到您的应用程序中。然后,创建描述患者个人信息的实例。使用加密的客户端将其插入到collection中,如以下示例所示:

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);
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",
},
},
};
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",
},
},
}
encrypted_collection = encrypted_client[encrypted_database_name][encrypted_collection_name]
result = encrypted_collection.insert_one(patient_document)

创建启用了 Queryable Encryption 的集合后,您可以查询加密字段。

后退

创建和查询