必须用 MongoDB Atlas 或企业版服务端,社区版不支持自动加密;Node.js 20 兼容驱动 v6.x,但 mongodb-client-encryption 主版本号须与 mongodb 驱动严格一致,且需配置 autoEncryption 选项、keyVaultNamespace、kmsProviders 和 schemaMap,并确保 DEK 由 createDataKey 生成而非硬编码。

必须用 MongoDB Atlas 或企业版服务端,社区版不支持自动加密;Node.js 20 没问题,但驱动版本要匹配 mongodb-client-encryption。
确认服务端支持 CSFLE 自动加密
社区版 MongoDB Server 4.2+ 不提供 mongocryptd 进程,而自动加密依赖它启动。即使你本地装了社区版,也会遇到类似错误:
MongoError: BSON field 'insert.jsonSchema' is an unknown field. This command may be meant for a mongocryptd process.
解决办法只有两个:
- 用
MongoDB Atlas(推荐学习/测试,免费层够用) - 本地部署
MongoDB Enterprise Edition(含mongocryptd,需单独安装并确保它在 PATH 中可执行)
注意:Atlas 实例本身不运行 mongocryptd,但它把加密逻辑卸载到服务端,客户端只需配好密钥和 schema 即可,无需本地启动该进程。
安装匹配的驱动与加密插件
Node.js 20 兼容驱动 v6.x,但 mongodb-client-encryption 的主版本号必须与 mongodb 驱动一致。比如你装的是 mongodb@6.7.0,那加密插件也得是 mongodb-client-encryption@6.7.0:
- 错配会导致
AutoEncrypter is not a constructor或初始化失败 - 不要用
^6.0.0这类宽泛 range,显式指定相同小版本号更稳 -
libmongocrypt是预编译二进制,国内 npm install 失败时,可设 registry 或用npm install --build-from-source
配置 MongoClient 启用自动加密
关键不是加个 flag,而是传入 autoEncryption 选项对象,并正确构造 keyVaultNamespace 和 kmsProviders:
-
kmsProviders至少要填{ local: { key: new Uint8Array(96).fill(0) } }(仅测试用;生产环境必须用 AWS/KMS/GCP 等真实 KMS) -
keyVaultNamespace格式为"db.collection",例如"encryption.__keyVault",且该集合必须已存在、有读写权限 -
schemaMap是可选但强烈建议的:直接传入 JSON Schema 对象,避免首次查询时向服务端请求 schema 导致延迟或失败
示例片段:
const client = new MongoClient(uri, {
autoEncryption: {
keyVaultNamespace: 'encryption.__keyVault',
kmsProviders: { local: { key: new Uint8Array(96).fill(0) } },
schemaMap: {
'medical.patients': {
properties: { ssn: { encrypt: { algorithm: 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic' } } }
}
}
}
});
容易被忽略的密钥管理细节
DEK(Data Encryption Key)不是你手动生成的字符串,而是通过 createDataKey 在 __keyVault 集合里插入后返回的 _id(BSON ObjectId 或 UUID),后续字段加密必须引用这个 ID:
- 不能硬编码
"abc123"这类占位符,否则解密失败且无明确报错 - 同一个 DEK 可复用于多个字段,但不同敏感等级建议分用不同 DEK
- 如果用
localKMS 测试,key字段必须是 96 字节的 Uint8Array,少一字节都会抛Invalid key length
真正上线前,务必验证解密路径:插入加密文档 → 断开重连新 client → find 返回明文字段。自动加密的“透明性”只在配置完全对齐时才成立,差一个字节、一个命名、一个权限,就静默降级为普通写入。











