MongoDB 6.0字段级加密必须依赖客户端字段级加密(CSFLE),所有加解密在驱动层完成,数据库仅存储密文;自动加密需通过schemaMap或远程JSON Schema配置,且encrypt.algorithm选错(如该用Deterministic却配Random)将导致等值查询失效。

MongoDB 6.0 中的字段级加密必须依赖客户端字段级加密(CSFLE),服务端不直接处理加密逻辑——所有加解密操作都在驱动层完成,数据库只存储密文。
自动加密模式下必须用 schemaMap 或远程 JSON Schema
自动加密不读取集合的 validator,也不支持在 createCollection 里嵌入加密规则。你只能通过两种方式之一提供加密模式:
-
autoEncryption.schemaMap:本地预置的 BSON Schema 对象,键为"db.collection"格式,值为符合 CSFLE 语法的 JSON Schema(不能含$jsonSchema验证关键字) - 不设
schemaMap,让驱动自动从 MongoDB 服务器拉取collection.options.validator中的$jsonSchema——但该 schema 必须是 Enterprise 6.0+ 集群上启用的、且仅含encrypt字段的合法子集
漏掉 schemaMap 又没配好远程 validator,MongoClient 初始化会静默跳过自动加密,写入的数据仍是明文,且无报错提示。
encrypt.algorithm 选错会导致查询失效
CSFLE 支持两种算法:AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic 和 AEAD_AES_256_CBC_HMAC_SHA_512-Random。区别不在安全性,而在查询能力:
- 用
Deterministic:相同明文总生成相同密文,支持find({ssn: "123-45-6789"})等值查询 - 用
Random:每次加密结果不同,无法做等值查询,但能防频率分析攻击
若业务需要按加密字段查数据(比如搜索用户邮箱),却误配成 Random,查询永远返回空——这不是 bug,是设计使然。检查方法:对同一值反复调用 encrypt(),看输出是否一致。
libmongocrypt 与 mongocryptd 的选择取决于驱动版本
Ruby、Node.js、Python 等主流驱动在 v2.19+ 默认使用 libmongocrypt(纯库,无需额外进程);v2.18 及更早则依赖 mongocryptd 进程。两者不兼容:
- 装了
mongocryptd但驱动是 v2.19+,它会忽略该进程,转而尝试加载libmongocrypt动态库 - 没装
libmongocrypt且驱动是 v2.19+,初始化MongoClient时抛出Failed to load libmongocrypt - macOS 上常见
dlopen(libmongocrypt.dylib, ...): image not found,需手动brew install libmongocrypt
别指望系统 PATH 里的 mongocryptd 能救 v2.19+ 的驱动——它根本不用那个二进制。
密钥管理中 keyId 必须是 UUID 格式 Base64 编码
CSFLE 加密规则中的 keyId 字段不是字符串 ID,而是 UUID 的 Base64 编码(非 hex)。例如:
keyId: [new Binary(Buffer.from("123e4567-e89b-12d3-a456-426614174000", "utf8"), 4)]
常见错误包括:
- 直接填字符串
"123e4567-e89b-12d3-a456-426614174000"→ 驱动解析失败,静默降级为未加密 - 用 hex 字符串转 Base64(如
"31323365..." → "MTEyMzM2ZTQ1NjctZTg5Yi0xMmQzLWE0NTYtNDI2NjE0MTc0MDAw")→ 解密时找不到对应 DEK - 在 KMS(如 GCP KMS)创建 CMK 后,没调用
createDataKey生成 DEK 并存入encryption.__keyVault→ 写入时报KeyNotFound
最稳的验证方式:用驱动的 encrypt() 方法手动加密一个测试值,再用 decrypt() 解出来——中间任何一步失败,都说明密钥链断了。


















