Use Explicit Encryption使用显式加密
On this page本页内容
Overview概述Before You Get Started开始之前Procedure过程Create a Customer Master Key创建客户主键Create a Unique Index on your Key Vault collection在键库集合上创建唯一索引Create your Data Encryption Keys and Encrypted Collection创建数据加密键和加密集合Configure your MongoClient for Encrypted Reads and Writes为加密读取和写入配置MongoClientInsert a Document with Encrypted Fields插入带有加密字段的文档Retrieve Your Document with Encrypted Fields使用加密字段检索文档Learn More了解更多信息
Overview概述
This guide shows you how to encrypt a document with explicit encryption and a MongoDB driver.本指南向您展示如何使用显式加密和MongoDB驱动程序加密文档。
After completing this guide, you should be able to configure a driver to encrypt fields in a document using explicit encryption. With this knowledge, you should be able to create a client application that uses explicit encryption. with automatic decryption.完成本指南后,您应该能够配置驱动程序,以便使用显式加密来加密文档中的字段。有了这些知识,您应该能够创建一个使用显式加密的客户端应用程序。具有自动解密功能。
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 Queryable Encryption enabled application that uses a remote Key Management System, see Tutorials.要查看演示如何创建使用远程键管理系统的启用可查询加密的应用程序的教程,请参阅教程。
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.要完成并运行本指南中的代码,您需要设置开发环境,如安装要求页面中所示。
See: Full Application请参阅:完整应用程序
To see the complete code for the application you make in this guide, select the tab corresponding to your preferred MongoDB driver and follow the provided link:要在本指南中查看您制作的应用程序的完整代码,请选择与您首选的MongoDB驱动程序相对应的选项卡,然后单击提供的链接:
Procedure过程
Create a Customer Master Key创建客户主键
You must create a Customer Master Key (CMK) to perform Queryable Encryption.必须创建客户主键(CMK)才能执行可查询加密。
Create a 96-byte Customer Master Key and save it to the file 创建一个96字节的客户主键,并将其保存到master-key.txt
: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);
}
Do Not Use a Local Key File in Production在生产中不要使用本地键文件
A local key file in your filesystem is insecure 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 Queryable Encryption implementation, see the Tutorials guide.要了解如何在可查询加密实现中使用远程KMS,请参阅教程指南。
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
的文件中。
See: Complete Code
To view the complete code for making a Customer Master Key, see the Queryable Encryption sample application repository.要查看制作客户主键的完整代码,请参阅可查询加密示例应用程序存储库。
Create a Unique Index on your Key Vault collection在键库集合上创建唯一索引
Create a unique index on the 在keyAltNames
field in your encryption.__keyVault
namespace.encryption.__keyVault
命名空间中的keyAltNames
字段上创建一个唯一索引。
Select the tab corresponding to your preferred MongoDB driver:选择与您首选的MongoDB驱动程序相对应的选项卡:
const uri = "<Your Connection String>";
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();
const keyVaultColl = keyVaultDB.collection(keyVaultCollection);
await keyVaultColl.createIndex(
{ keyAltNames: 1 },
{
unique: true,
partialFilterExpression: { keyAltNames: { $exists: true } },
}
);
Create your Data Encryption Keys and Encrypted Collection创建数据加密键和加密集合
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. 将CMK值传递给您的KMS提供程序设置。The client uses these settings to discover the CMK. Set the provider name to 客户端使用这些设置来发现CMK。将提供程序名称设置为本地,以通知驱动程序您正在使用本地键提供程序。local
to inform the driver you are using a Local Key Provider.
Select the tab corresponding to your preferred MongoDB driver:选择与您首选的MongoDB驱动程序相对应的选项卡:
const provider = "local";
const path = "./master-key.txt";
//WARNING: Do not use a local key file in a production application警告:请勿在生产应用程序中使用本地键文件
const localMasterKey = fs.readFileSync(path);
const kmsProviders = {
local: {
key: localMasterKey,
},
};
Create your Data Encryption Keys创建数据加密键
Construct a client with your MongoDB connection string and Key Vault collection namespace, and create the Data Encryption Keys:使用MongoDB连接字符串和键库集合命名空间构建客户端,并创建数据加密键:
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 clientEnc = new ClientEncryption(keyVaultClient, {
keyVaultNamespace: keyVaultNamespace,
kmsProviders: kmsProviders,
});
const dek1 = await clientEnc.createDataKey(provider, {
keyAltNames: ["dataKey1"],
});
const dek2 = await clientEnc.createDataKey(provider, {
keyAltNames: ["dataKey2"],
});
Create Your Encrypted Collection创建加密集合
Use a Queryable Encryption enabled 使用启用可查询加密的MongoClient
instance to specify what fields you must encrypt and create your encrypted collection:MongoClient
实例指定必须加密的字段并创建加密的集合:
const encryptedFieldsMap = {
[`${secretDB}.${secretCollection}`]: {
fields: [
{
keyId: dek1,
path: "patientId",
bsonType: "int",
queries: { queryType: "equality" },
},
{
keyId: dek2,
path: "medications",
bsonType: "array",
},
],
},
};
const extraOptions = {
cryptSharedLibPath: "<path to FLE Shared Library>",
};
const encClient = new MongoClient(uri, {
autoEncryption: {
keyVaultNamespace,
kmsProviders,
extraOptions,
encryptedFieldsMap,
},
});
await encClient.connect();
const newEncDB = encClient.db(secretDB);
//Drop the encrypted collection in case you created this collection in a previous run of this application.如果您在以前运行此应用程序时创建了此集合,请删除加密的集合。
await newEncDB.dropDatabase();
await newEncDB.createCollection(secretCollection);
console.log("Created encrypted collection!");
The output from the code in this section should resemble the following:本节中代码的输出应类似于以下内容:
Created encrypted collection!
See: Complete Code请参阅:完整代码
To view the complete code for making a Data Encryption Key, see the Queryable Encryption sample application repository.要查看制作数据加密键的完整代码,请参阅可查询加密示例应用程序存储库。
Configure your MongoClient for Encrypted Reads and Writes为加密读取和写入配置MongoClient
Specify the Key Vault Collection Namespace指定键保管库集合命名空间
Specify 指定encryption.__keyVault
as the Key Vault collection namespace.encryption.__keyVault
作为Key Vault集合命名空间。
const eDB = "encryption";
const eKV = "__keyVault";
const keyVaultNamespace = `${eDB}.${eKV}`;
const secretDB = "medicalRecords";
const secretCollection = "patients";
Specify the Customer Master Key指定客户主键
Specify the KMS provider and specify your Customer Master Key inline:指定KMS提供程序并内联指定您的客户主键:
const fs = require("fs");
const path = "./master-key.txt";
// WARNING: Do not use a local key file in a production application
const localMasterKey = fs.readFileSync(path);
const kmsProviders = {
local: {
key: localMasterKey,
},
};
Retrieve Data Encryption Keys检索数据加密键
Retrieve the Data Encryption Keys created in the Create a Data Encryption Key step of this guide:检索在本指南的创建数据加密键步骤中创建的数据加密键:
const uri = "<Your MongoDB URI>";
const unencryptedClient = new MongoClient(uri);
await unencryptedClient.connect();
const keyVaultClient = unencryptedClient.db(eDB).collection(eKV);
const dek1 = await keyVaultClient.findOne({ keyAltNames: "dataKey1" });
const dek2 = await keyVaultClient.findOne({ keyAltNames: "dataKey2" });
Specify the Path of the Automatic Encryption Shared Library指定自动加密共享库的路径
const extraOptions = {
cryptSharedLibPath: "<path to crypt_shared library>",
};
Learn More了解更多信息
To learn more about the library referenced by this path, see the Automatic Encryption Shared Library for Queryable Encryption page.要了解有关此路径引用的库的更多信息,请参阅可查询加密的自动加密共享库页面。
Create a MongoClient Object创建MongoClient
对象
Instantiate a 使用以下自动加密设置实例化MongoClient
object with the following automatic encryption settings:MongoClient
对象:
const encryptedClient = new MongoClient(uri, {
autoEncryption: {
kmsProviders: kmsProviders,
keyVaultNamespace: keyVaultNamespace,
bypassQueryAnalysis: true,
keyVaultClient: unencryptedClient,
extraOptions: extraOptions,
},
});
await encryptedClient.connect();
Automatic Decryption自动解密
We use a 我们使用启用了自动加密的MongoClient
instance with automatic encryption enabled to perform automatic decryption.MongoClient
实例来执行自动解密。
To learn more about explicit encryption with automatic decryption, see the Fundamentals section.要了解有关使用自动解密的显式加密的更多信息,请参阅基础知识部分。
Insert a Document with Encrypted Fields插入带有加密字段的文档
Use your Queryable Encryption enabled 使用启用可查询加密的MongoClient
instance to insert a document with encrypted fields into the medicalRecords.patients
namespace using the following code snippet:MongoClient
实例,使用以下代码片段将具有加密字段的文档插入medicalRecords.patients
命名空间:
const patientId = 12345678;
const medications = ["Atorvastatin", "Levothyroxine"];
const indexedInsertPayload = await encryption.encrypt(patientId, {
algorithm: "Indexed",
keyId: dek1._id,
contentionFactor: 1,
});
const unindexedInsertPayload = await encryption.encrypt(medications, {
algorithm: "Unindexed",
keyId: dek2._id,
});
const encryptedColl = encryptedClient
.db(secretDB)
.collection(secretCollection);
await encryptedColl.insertOne({
firstName: "Jon",
patientId: indexedInsertPayload,
medications: unindexedInsertPayload,
});
When you insert a document, your Queryable Encryption enabled client encrypts the fields of your document such that it resembles the following:插入文档时,启用可查询加密的客户端会对文档的字段进行加密,使其类似于以下内容:
{
"_id": {
"$oid": "6303e36053cc7ec2e6a630bd"
},
"firstName": "Jon",
"patientId": {
"$binary": {
"base64": "BxLJUBmg703civqMz8ASsD4QEYeSneOGiiYHfLE77ELEkp1EC/fXPrKCNRQl2mAFddszqDJ0P3znKrq0DVMEvJoU6wa0Ra+U+JjNVr8NtJE+TpTLCannY5Av6iGfLAaiHbM/E8Ftz1YCQsArQwuNp3wIV/GJPLa2662xsyk0wz7F6IRGC3FlnxpN4UIFaHE1M7Y6kEnx3tEy5uJBvU4Sex7I2H0kqHthClH77Q6xHIHc8H9d6upvgnEbkKBCnmc24A2pSG/xZ7LBsV3j5aOboPISuN/lvg==",
"subType": "06"
}
},
"medications": {
"$binary": {
"base64": "BvOsveapfUxiuQxCMSM2fYIEyRlQaSqR+0NxlMarwurBflvoMz1FrSjSGgCVCpK8X+YrilP6Bac99kkaUmRJfjo4savxcjpOfEnUj5bHciPyfQBYmYF4PMLDtTTzGZpPilb9d5KgpIMBXxHi+dIcog==",
"subType": "06"
}
},
"__safeContent__": [
{
"$binary": {
"base64": "ZLPIpgxzXpHUGrvdIHetwmMagR+mqvuUj5nzXNGf/WM=",
"subType": "00"
}
}
]
}
Do not Modify the __safeContent__ Field不要修改__safeContent__
字段
The __safeContent__
field is essential to Queryable Encryption. Do not modify the contents of this field.__safeContent__
字段对于可查询加密至关重要。请勿修改此字段的内容。
See: Complete Code请参阅:完整代码
To view the complete code to insert a document encrypted with explicit encryption, see the Queryable Encryption sample application repository.要查看插入使用显式加密加密的文档的完整代码,请参阅可查询加密示例应用程序存储库。
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 through a query on an encrypted field:通过对加密字段的查询,检索您在本指南的插入带加密字段的文档步骤中插入的带加密字段文档:
const findPayload = await encryption.encrypt(patientId, {
algorithm: "Indexed",
keyId: dek1._id,
queryType: "equality",
contentionFactor: 1,
});
console.log("Finding a document with manually encrypted field:");
console.log(await encryptedColl.findOne({ patientId: findPayload }));
The output of the preceding code snippet should contain the following document:前面代码段的输出应该包含以下文档:
{
"__safeContent__": [
{
"Subtype": 0,
"Data": "LfaIuWm9o30MIGrK7GGUoStJMSNOjRgbxy5q2TPiDes="
}
],
"_id": "6303a770857952ca5e363fd2",
"firstName": "Jon",
"medications": ["Atorvastatin", "Levothyroxine"],
"patientId": 12345678
}
See: Complete Code请参阅:完整代码
To view the code to retrieve your document with encrypted fields, see the Queryable Encryption sample application repository.要查看用于检索具有加密字段的文档的代码,请参阅可查询加密示例应用程序存储库。
Learn More了解更多信息
To view a tutorial on using Queryable Encryption with a remote KMS, see Tutorials.要查看有关在远程KMS中使用可查询加密的教程,请参阅教程。
To learn how Queryable Encryption works, see Explicit Encryption.要了解可查询加密的工作原理,请参阅显式加密。
To learn more about the topics mentioned in this guide, see the following links:要了解有关本指南中提到的主题的更多信息,请参阅以下链接: