You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Mongoose中配置Client-Side Field Level Encryption

基于Mongoose实现客户端字段级加密(CSFLE)的配置方案

前置依赖

  • MongoDB版本为4.2+企业版/Atlas集群,Mongoose版本为6.0+
  • 安装所需依赖:npm install mongodb mongodb-client-encryption mongoose
  • 提前准备主密钥:测试环境可本地生成96字节随机密钥,生产环境建议托管到云KMS服务

步骤1:生成测试用本地主密钥

const crypto = require('crypto');
// 96字节随机主密钥,生产环境禁止硬编码,需存储在安全的KMS服务中
const masterKey = crypto.randomBytes(96);

步骤2:配置带加密能力的Mongoose连接

const mongoose = require('mongoose');
const { ClientEncryption } = require('mongodb-client-encryption');

const encryptionConfig = {
  keyVaultNamespace: 'encryption.__keyVault', // 存储数据加密密钥的专属集合
  kmsProviders: {
    local: {
      key: masterKey
    }
  }
};

// 建立带自动加密能力的数据库连接
const connectWithCSFLE = async () => {
  await mongoose.connect('mongodb://localhost:27017/your_business_db', {
    autoEncryption: encryptionConfig
  });
};

步骤3:生成数据加密密钥(DEK)

const createDataKey = async () => {
  const encryptionClient = new ClientEncryption(mongoose.connection.getClient(), {
    keyVaultNamespace: encryptionConfig.keyVaultNamespace,
    kmsProviders: encryptionConfig.kmsProviders
  });
  // 返回生成的数据加密密钥ID,后续配置Schema时使用
  return await encryptionClient.createDataKey('local');
};

步骤4:定义带加密字段的Mongoose Schema

支持两种加密算法:

  • AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic:确定性加密,相同明文加密结果一致,支持等值查询
  • AEAD_AES_256_CBC_HMAC_SHA_512-Random:随机加密,相同明文加密结果不同,安全性更高,不支持查询
const userSchema = new mongoose.Schema({
  username: String,
  // 加密字段:身份证号,支持等值查询
  idCard: {
    type: String,
    encrypt: {
      key: dataKeyId, // 替换为步骤3生成的dataKeyId
      algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
    }
  },
  // 加密字段:银行卡号,不支持查询,安全性更高
  bankCard: {
    type: String,
    encrypt: {
      key: dataKeyId,
      algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
    }
  }
});

const User = mongoose.model('User', userSchema);

步骤5:验证加密效果

加密解密全流程在客户端自动完成,业务侧无需额外处理逻辑

// 插入数据时敏感字段自动加密
await User.create({
  username: '张三',
  idCard: '110101199001011234',
  bankCard: '6222021234567890123'
});

// 查询数据时敏感字段自动解密
const user = await User.findOne({ username: '张三' });
console.log(user.idCard); // 输出明文:110101199001011234

注意事项:

  1. 不要对_id、索引字段、关联字段进行加密,会导致索引失效、关联查询异常
  2. 数据加密密钥和主密钥不要与业务数据存储在同一数据库实例,避免密钥泄露
  3. 确定性加密会暴露明文重复特征,仅在需要等值查询的场景下使用

内容的提问来源于stack exchange,提问作者Yehuda_Fievel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 21:45:02