对于 AI 代理:可在 https://www.mongodb.com/zh-cn/docs/llms.txt 获取文档索引—通过在任何 URL 路径后添加 .md 可获取所有页面的 Markdown 版本。
Docs 菜单

正在使用的加密

您可以使用 Node.js 驱动程序通过一组称为正在使用的加密的功能来加密特定文档字段。通过正在使用的加密,您的应用程序在将数据发送到 MongoDB之前 对数据进行加密,并使用加密字段查询文档。

警告

MongoDB 8.2已知问题

mongocryptd 的 8.2.0 版本可能无法在Windows上运行。如果您在启动 mongocryptd 时指定 --logpath NUL 参数,此错误会影响驱动程序的“正在使用的加密” 。

要学习;了解有关此问题及其解决方法的详情,请参阅MongoDB.8 发布说明中的已知问题。2

正在使用的加密可以防止未经授权的用户查看发送到 MongoDB 或位于加密数据库中的明文数据。要在应用程序中启用正在使用的加密并授权其解密数据,必须创建只有应用程序才能访问的加密密钥。只有有权访问加密密钥的应用程序才能访问解密的明文数据。如果攻击者获得对数据库的访问权限,他们只能看到加密的密文数据,因为他们无法访问加密密钥。

您可以使用正在使用的加密来加密 MongoDB 文档中包含以下类型敏感数据的字段:

  • 信用卡号码

  • 地址

  • 健康信息

  • 财务信息

  • 任何其他敏感信息或个人身份信息 (PII)

MongoDB 提供以下功能来启用正在使用的加密:

Queryable Encryption (QE) 是一种正在使用的加密功能,可让您对加密字段值运行查询,包括相等、范围、前缀、后缀和子字符串查询。范围查询支持需要 MongoDB Server 8.0 或更高版本。前缀、后缀和子字符串查询支持需要 MongoDB Server 9.0 或更高版本。

要学习;了解有关Queryable Encryption的更多信息,请参阅MongoDB Server手册中的Queryable Encryption 。

在 MongoDB Server 4.2 版中引入客户端字段级加密 (CSFLE),支持搜索加密字段的相等性。CSFLE 与 Queryable Encryption 的不同之处在于,您可以选择确定性或随机加密算法来加密字段。 使用 CSFLE 时只能查询使用确定性加密算法的加密字段。当使用随机加密算法对 CSFLE 的字段进行加密时,可以解密这些字段,但不能对这些字段进行相等性查询。使用 Queryable Encryption 时,不能指定加密算法,但可以查询所有加密字段。

当您确定性地加密一个值时,相同的输入值会产生相同的输出值。虽然确定性的加密允许您对这些加密字段执行查询,但关联基数较低的加密数据很容易因频率分析而遭遇密码破解。

提示

要了解有关这些概念的更多信息,请参阅以下维基百科条目:

要了解有关 CSFLE 的更多信息,请参阅服务器手册中的 CSFLE。

从MongoDB Server 8.1 开始,您可以将 $lookup聚合阶段与配置为正在使用的加密的客户端一起使用。此功能需要 mongodb-client-encryption包版本 6.3.0 或更高版本。

$lookup 阶段允许您跨加密集合连接相关数据,而无需在应用程序代码中手动获取和组合文档。源集合和 from集合都必须配置为正在使用的加密。localField 和 foreignField 中指定的字段不得是加密字段。

以下示例展示了对加密集合执行的 $lookup 操作:

const pipeline = [
{
$lookup: {
from: "encryptedCollection",
localField: "userId",
foreignField: "_id",
as: "userDetails"
}
}
];
const results = await collection.aggregate(pipeline).toArray();

从 Node.js驾驶员版本 7.6 开始,您可以通过HTTP 代理将 Node.js驾驶员向密钥管理系统 (KMS ) 发出的请求路由。当您的环境需要出站KMS流量通过HTTP转发代理时,请使用此功能。 proxyOptions 设置仅支持 SOCKS5协议,不包括这种情况。

要控制驾驶员连接到KMS托管的方式,请在 ClientEncryptionOptions对象或 AutoEncryptionOptions对象上设立kmsConnectCallback 选项。设立此选项后,驾驶员会调用回调,而不是连接到KMS托管本身。该回调接收以下属性:

属性
说明

host

驾驶员必须访问的KMS托管的主机名。

port

驾驶员必须访问的KMS托管端口。

timeoutMS

操作的客户端操作超时 (CSOT) 预算中的剩余时间(以毫秒为单位)。如果操作未配置 CSOT,则此属性为 undefined。

signal

当连接尝试超过超时预算时中止的 AbortSignal。当信号触发时,回调必须停止连接并拒绝。

以下示例定义了一个回调,该回调通过向代理发送HTTP CONNECT请求来打开通往KMS托管的隧道,然后将该回调传递给 ClientEncryption实例:

import * as net from "net";
const kmsConnectCallback = ({ host, port, timeoutMS, signal }) =>
new Promise((resolve, reject) => {
// Opens a plain connection to the proxy, not to the KMS host.
// Passing signal lets Node abort the connection attempt when the
// driver's timeout budget expires.
const socket = net.connect({
host: "proxy.example.com",
port: 8080,
signal
});
// Applies the remaining CSOT budget to the proxy handshake, so that
// a proxy that accepts the connection but never answers CONNECT
// can't stall the operation.
if (timeoutMS !== undefined) {
socket.setTimeout(timeoutMS, () => {
socket.destroy();
reject(new Error("Timed out waiting for the proxy"));
});
}
socket.once("error", reject);
socket.once("connect", () => {
// Asks the proxy to tunnel to the KMS host
socket.write(
`CONNECT ${host}:${port} HTTP/1.1\r\n` +
`Host: ${host}:${port}\r\n\r\n`
);
socket.once("data", chunk => {
if (chunk.toString("utf8").startsWith("HTTP/1.1 200")) {
// Clears the handshake timeout and returns the socket so that
// the driver can perform the TLS handshake
socket.setTimeout(0);
resolve(socket);
} else {
socket.destroy();
reject(new Error("Proxy refused the CONNECT request"));
}
});
});
});
const clientEncryption = new ClientEncryption(keyVaultClient, {
keyVaultNamespace,
kmsProviders,
kmsConnectCallback
});

signal属性适用于与代理的连接,timeoutMS属性适用于 CONNECT 交换。在 CONNECT 交换结束后,套接字超时保持活动状态,因此在解析承诺之前清除超时。否则,驾驶员执行 TLS 握手时,超时可能会破坏套接字。

前面的示例已压缩以显示调用顺序。在生产代码中,缓冲代理的响应,直到收到标头区块的末尾,因为响应可以跨多个数据段到达。

重要

kmsConnectCallback 和 proxyOptions 选项是互斥的。如果设立kmsConnectCallback 并在 proxyOptions 中指定 proxyHost 值,则驾驶员会引发 MongoCryptInvalidArgumentError。