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

正在使用的加密

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

警告

MongoDB 8.2已知问题

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

要学习;了解有关此问题及其解决方法的更多信息,请参阅MongoDB8.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();

重要

对于配置为使用客户端字段级加密或 Queryable Encryption 进行自动加密的客户端,不支持 $rerank 阶段。包含 $rerank 的管道会失败,并出现类似 Unrecognized pipeline stage name: '$rerank' 的错误。

该限制适用于所有集合,包括没有加密字段的集合,以及在子管道(例如 $unionWith)中使用 $rerank 的情况。

从 Node.js 驱动程序 7.6 版本开始,您可以通过 HTTP proxy 路由 Node.js 驱动程序向您的密钥管理系统 (KMS) 发出的请求。当您的环境需要外发 KMS 流量通过 HTTP 正向代理时,使用此功能。proxyOptions 设置仅支持 SOCKS5 协议,并不涉及此类情况。

要控制驱动程序连接 KMS 托管的方式,请在 ClientEncryptionOptions 对象或 AutoEncryptionOptions 对象上设置 kmsConnectCallback 选项。当您设置此选项时,驱动程序会调用您的回调,而不是连接到 KMS 托管本身。回调接收以下属性:

属性
说明

host

驱动程序必须访问的 KMS 托管的主机名。

port

驱动程序必须访问的 KMS 托管端口。

timeoutMS

在 Node.js 驱动程序 7.8 及更高版本中已弃用。此属性无效,并计划在未来版本中删除。在较早的驱动程序版本中,它包含操作的客户端操作超时预算中剩余的时间(以毫秒为单位)。

signal

当操作中止时会中止的 AbortSignal。当信号触发时,您的回调必须停止连接并拒绝。

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

import * as net from "net"; const kmsConnectCallback = ({ host, port, 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 aborts the operation. const socket = net.connect({ host: "proxy.example.com", port: 8080, signal }); // Guards against a proxy that accepts the connection but stops // responding. The driver applies no timeout to the KMS connection, // so use an application-chosen idle timeout. It stays active after // the CONNECT exchange, so it also covers the TLS handshake and // KMS request that the driver performs over this socket. socket.setTimeout(10000, () => { socket.destroy(new Error("KMS connection timed out")); }); 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")) { // Returns the socket so that the driver can perform the // TLS handshake resolve(socket); } else { socket.destroy(); reject(new Error("Proxy refused the CONNECT request")); } }); }); }); const clientEncryption = new ClientEncryption(keyVaultClient, { keyVaultNamespace, kmsProviders, kmsConnectCallback});

signal 属性适用于与代理的连接。当操作被中止时,信号会触发,节点会停止连接尝试。

setTimeout() 调用可防止代理接受连接但停止响应的情况。驱动程序不会对 kmsConnectCallback 或随后的 KMS 请求应用超时。如果没有选择空闲超时,操作可能会挂起。如果 10 秒内套接字上没有数据到达,则会触发超时。它在 CONNECT 交换后保持活动状态,因此它也涵盖了 TLS 握手和驱动程序通过隧道发送的 KMS 请求。当超时触发时,示例会将错误传递给 socket.destroy(),这会拒绝挂起的操作。驱动程序在每次 KMS 请求后都会关闭套接字。

前面的示例已经简化,以显示调用顺序。在生产代码中,缓冲代理的响应,直到收到头部数据块的结尾,因为响应可以通过多个数据块到达。

重要

kmsConnectCallback 和 proxyOptions 选项互斥。如果您设置 kmsConnectCallback 并在 proxyOptions 中指定 proxyHost 值,则驱动程序会报出 MongoCryptInvalidArgumentError。