文档菜单
文档首页
/
MongoDB 手册
/ / / / / /

创建加密集合并插入文档

本页内容

  • 概述
  • 开始之前
  • 步骤
  • 下一步

本指南展示了如何创建一个启用可查询加密的集合,并插入一个具有加密字段的文档。

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

在创建加密集合之前,请先创建您的可查询加密应用

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

1

要加密一个字段,请将其添加到加密模式。要启用字段上的查询,请添加queries 属性。您可以通过等值查询或范围查询启用可查询的字段。以下步骤演示了如何根据每种查询类型指定要加密的字段。

  1. 指定等值查询的字段

    要启用字段上的等值查询,请将字段添加到加密模式,并设置 queryType"equality"。以下代码示例加密了 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. 指定范围查询的字段

    要启用字段上的范围查询,请将字段添加到加密模式,并设置 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 }],
    },
    ]
    }

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

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# 版本使用单独的类作为数据模型来表示文档结构。将以下 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 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,
)

提示

数据库名称与数据库

创建加密集合的方法需要一个数据库 对象 的引用,而不是数据库 名称。您可以通过客户端对象上的方法获取此引用。

有关更多信息,请参阅 创建集合时启用可查询加密。

4

创建一个描述病人个人信息的示例文档。使用加密客户端将其插入到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

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

将这些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)

创建一个启用可查询加密的集合后,您可以查询加密字段。

返回

创建和查询