Docs HomeDevelop ApplicationsMongoDB Manual

Quick Start快速入门

MongoDB's Queryable Encryption feature is available (GA) in MongoDB 7.0 and later. To learn more about Queryable Encryption and compare its benefits with Client-Side Field Level Encryption, see Queryable Encryption.

Overview概述

This guide shows you how to encrypt a document with automatic Client-Side Field Level Encryption (CSFLE) and a MongoDB driver.本指南向您展示如何使用自动客户端字段级加密(CSFLE)和MongoDB驱动程序加密文档。

After completing this guide, you should have the following knowledge and software:完成本指南后,您应该具备以下知识和软件:

  • Knowledge of the steps to configure a driver to encrypt fields in a document.了解配置驱动程序以加密文档中字段的步骤。
  • A working, but not production-ready, client application that utilizes automatic Client-Side Field Level Encryption.一种正在工作但尚未准备好生产的客户端应用程序,它使用自动客户端字段级加密。
Important

Do Not Use this Application In Production请勿在生产中使用此应用程序

Since this example application stores an encryption key on your application's filesystem, you risk unauthorized access to the key or loss of the key to decrypt your data.由于此示例应用程序将加密键存储在应用程序的文件系统上,因此您可能会面临未经授权访问键或丢失解密数据的键的风险。

To view a tutorial that demonstrates how to create a production-ready CSFLE-enabled application, see Tutorials.要查看演示如何创建支持CSFLE的生产应用程序的教程,请参阅教程

Before You Get Started开始之前

To complete and run the code in this guide, you need to set up your development environment as shown in the Installation Requirements page.要完成并运行本指南中的代码,您需要设置开发环境,如安装要求页面中所示。

Select the programming language for which you want to see code examples for from the Select your language dropdown menu on the right side of the page.从页面右侧的“选择语言”下拉菜单中选择要查看其代码示例的编程语言。

Tip

See: Full Application请参阅:完整应用程序

To view the complete runnable application code for this tutorial, go to the following link:要查看本教程的完整可运行应用程序代码,请转到以下链接:

Procedure过程

// You are viewing the Node.js driver code examples.您正在查看Node.js驱动程序代码示例。
// Use the dropdown menu to select a different driver.使用下拉菜单选择不同的驱动程序。
1

Create a Customer Master Key创建客户主键

You must create a Customer Master Key (CMK) to perform CSFLE.您必须创建一个客户主键(CMK)才能执行CSFLE。

Create a 96-byte Customer Master Key and save it in your Local Key Provider, which is your filesystem, as the file master-key.txt:创建一个96字节的客户主键,并将其保存在您的文件系统本地键提供程序中,作为master-key.txt

const fs = require("fs");
const crypto = require("crypto");
try {
fs.writeFileSync("master-key.txt", crypto.randomBytes(96));
} catch (err) {
console.error(err);
}
Warning

Do Not Use the Local Key Provider in Production请勿在生产中使用本地键提供程序

The Local Key Provider is an insecure method of storage and is not recommended for production. 本地键提供程序是一种不安全的存储方法,不建议用于生产。Instead, you should store your Customer Master Keys in a remote Key Management System (KMS).相反,您应该将客户主键存储在远程键管理系统(KMS)中。

To learn how to use a remote KMS in your CSFLE implementation, see the Tutorials guide.要了解如何在CSFLE实现中使用远程KMS,请参阅教程指南。

Tip

Generate a CMK from the Command Line从命令行生成CMK

Use the following command to generate a CMK from a Unix shell or PowerShell:使用以下命令从Unix shell或PowerShell生成CMK

  • Unix shell:

    echo $(head -c 96 /dev/urandom | base64 | tr -d '\n')
  • PowerShell:

    $r=[byte[]]::new(64);$g=[System.Security.Cryptography.RandomNumberGenerator]::Create();$g.GetBytes($r);[Convert]::ToBase64String($r)

Save the output of the preceding command to a file named master-key.txt.将前面命令的输出保存到名为master-key.txt的文件中。

Tip

See: Complete Code请参阅:完整代码

2

Create a Unique Index on your Key Vault collection在键库集合上创建唯一索引

Create a partial unique index on the keyAltNames field in your encryption.__keyVault namespace. This index should have a partialFilterExpression for documents where keyAltNames exists.encryption.__keyVault命名空间中的keyAltNames字段上创建部分唯一索引。对于存在keyAltNames的文档,此索引应具有partialFilterExpression

Client-Side Field Level Encryption depends on server-enforced uniqueness of key alternate names.客户端字段级加密取决于服务器强制的键备用名称的唯一性。

Select the tab corresponding to your preferred MongoDB driver:选择与您首选的MongoDB驱动程序相对应的选项卡:

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.删除存储加密字段的数据库,因为加密这些字段的所有DEK都已在前一行中删除。
await keyVaultClient.db("medicalRecords").dropDatabase();
const keyVaultColl = keyVaultDB.collection(keyVaultCollection);
await keyVaultColl.createIndex(
{ keyAltNames: 1 },
{
unique: true,
partialFilterExpression: { keyAltNames: { $exists: true } },
}
);
3

Create a Data Encryption Key创建数据加密键

1

Read the Customer Master Key and Specify KMS Provider Settings读取客户主键并指定KMS提供程序设置

Retrieve the contents of the Customer Master Key file that you generated in the Create a Customer Master Key step of this guide.检索您在本指南的创建客户主键步骤中生成的客户主键文件的内容。

Pass the CMK value to your KMS provider settings. The client uses these settings to discover the CMK. As you are using the Local Key Provider, set the provider name to local.CMK值传递给您的KMS提供程序设置。客户端使用这些设置来发现CMK。使用本地键提供程序时,请将提供程序名称设置为Local。

const provider = "local";
const path = "./master-key.txt";
const localMasterKey = fs.readFileSync(path);
const kmsProviders = {
local: {
key: localMasterKey,
},
};
2

Create a Data Encryption Key创建数据加密键

Construct a client with your MongoDB connection string and Key Vault collection namespace, and create a Data Encryption Key:使用MongoDB连接字符串和键库集合命名空间构建客户端,并创建数据加密键:

Note

Key Vault Collection Namespace Permissions键保管库集合命名空间权限

The Key Vault collection is in the encryption.__keyVault namespace. 键保管库集合处于encryption.__keyVault命名空间。Ensure that the database user your application uses to connect to MongoDB has ReadWrite permissions on this namespace.确保应用程序用于连接MongoDB的数据库用户对此命名空间具有ReadWrite权限。

const client = new MongoClient(uri, {
useNewUrlParser: true,
useUnifiedTopology: true,
});
await client.connect();

const encryption = new ClientEncryption(client, {
keyVaultNamespace,
kmsProviders,
});
const key = await encryption.createDataKey(provider);
console.log("DataKeyId [base64]: ", key.toString("base64"));
await keyVaultClient.close();
await client.close();

The output from the code above should resemble the following:上面代码的输出应该类似于以下内容:

DataKeyId [base64]: 3k13WkSZSLy7kwAAP4HDyQ==
Tip

See: Complete Code请参阅:完整代码

4

Configure the MongoClient配置MongoClient

1

Specify the Key Vault Collection Namespace指定键保管库集合命名空间

Specify encryption.__keyVault as the Key Vault collection namespace.指定encryption.__keyVault作为Key Vault集合命名空间。

const keyVaultNamespace = "encryption.__keyVault";
2

Specify the Local Customer Master Key指定本地客户主键

Specify the KMS provider and specify your key inline:指定KMS提供程序并内联指定键:

const fs = require("fs");
const provider = "local";
const path = "./master-key.txt";
const localMasterKey = fs.readFileSync(path);
const kmsProviders = {
local: {
key: localMasterKey,
},
};
3

Create an Encryption Schema For Your Collection为您的集合创建加密架构

Tip

Add Your Data Encryption Key Base64 ID添加您的数据加密键Base64 ID

Make sure to update the following code to include your Base64 DEK ID. You received this value in the Generate your Data Encryption Key step of this guide.请确保更新以下代码以包含您的Base64 DEK ID。您在本指南的生成数据加密键步骤中收到了此值。

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;
4

Specify the Location of the Automatic Encryption Shared Library指定自动加密共享库的位置

const extraOptions = {
cryptSharedLibPath: "<Full path to your Automatic Encryption Shared Library>",
};
Note

Automatic Encryption Options自动加密选项

The automatic encryption options provide configuration information to the Automatic Encryption Shared Library, which modifies the application's behavior when accessing encrypted fields.自动加密选项为自动加密共享库提供配置信息,该库在访问加密字段时修改应用程序的行为。

To learn more about the Automatic Encryption Shared Library, see the Automatic Encryption Shared Library for CSFLE page.要了解有关自动加密共享库的更多信息,请参阅CSFLE的自动加密共享库页

5

Create the MongoClient创建MongoClient

Instantiate a MongoDB client object with the following automatic encryption settings:使用以下自动加密设置实例化MongoDB客户端对象:

const secureClient = new MongoClient(connectionString, {
useNewUrlParser: true,
useUnifiedTopology: true,
autoEncryption: {
keyVaultNamespace,
kmsProviders,
schemaMap: patientSchema,
extraOptions: extraOptions,
},
});
5

Insert a Document with Encrypted Fields插入带有加密字段的文档

Use your CSFLE-enabled MongoClient instance to insert a document with encrypted fields into the medicalRecords.patients namespace using the following code snippet:使用启用CSFLE的MongoClient实例,使用以下代码片段将具有加密字段的文档插入medicalRecords.patients命名空间:

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);
}

When you insert a document, your CSFLE-enabled client encrypts the fields of your document such that it resembles the following:插入文档时,启用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"
}
}
}
Tip

See: Complete Code请参阅:完整代码

6

Retrieve Your Document with Encrypted Fields使用加密字段检索文档

Retrieve the document with encrypted fields you inserted in the Insert a Document with Encrypted Fields step of this guide.检索您在本指南的插入带加密字段的文档步骤中插入的带加密字段文档。

To show the functionality of CSFLE, the following code snippet queries for your document with a client configured for automatic CSFLE as well as a client that is not configured for automatic CSFLE.为了显示CSFLE的功能,以下代码片段查询您的文档,其中客户端配置为自动CSFLE,客户端未配置为自动CSFLE。

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" })
);

The output of the preceding code snippet should look like this:前面的代码片段的输出应该如下所示:

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' }
}
Tip

See: Complete Code请参阅:完整代码

Learn More了解更多信息

To view a tutorial on production-ready CSFLE with a remote KMS, see Tutorials.要查看有关使用远程KMS的生产就绪CSFLE的教程,请参阅教程

To learn how CSFLE works, see Fundamentals.要了解CSFLE的工作原理,请参阅基础知识

To learn more about the topics mentioned in this guide, see the following links:要了解有关本指南中提到的主题的更多信息,请参阅以下链接: