客户端字段级加密
学习者将配置 MongoDB 的客户端字段级加密,在敏感字段离开应用程序前对其进行加密,避免明文出现在服务器中。
客户端字段级加密 是 CoddyKit 上的免费 MongoDB Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 MongoDB Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 MongoDB Academy 课程共包含 4 节课。
本课时的部分内容尚未翻译,以英文显示。
Why Field-Level Encryption?
Even with TLS and encryption at rest, the MongoDB server sees plaintext data once it is decrypted from disk. A compromised DBA account, a rogue cloud engineer with disk access, or a database backup leak could expose sensitive fields. Client-Side Field Level Encryption (CSFLE) solves this by encrypting individual sensitive fields — like SSNs, credit card numbers, or health data — inside the client driver, before the data ever reaches the server. The server only ever stores ciphertext.
How CSFLE Works at a High Level
CSFLE uses two layers of keys. The Customer Master Key (CMK) is stored in an external Key Management System (AWS KMS, Azure Key Vault, GCP KMS, or a local key). The CMK encrypts a Data Encryption Key (DEK), which is stored in a MongoDB collection called the Key Vault. The driver fetches and decrypts the DEK using the CMK at query time, then uses the DEK to encrypt/decrypt individual field values. The server never sees the CMK or the DEK in plaintext.
Two Modes: Automatic and Explicit
CSFLE offers two encryption modes. Automatic CSFLE (requires MongoDB Enterprise or Atlas) encrypts and decrypts fields transparently based on a JSON schema — your application code does not change. Explicit (Manual) CSFLE is available in the Community driver and requires the application to call encrypt/decrypt methods explicitly. Automatic is far more convenient for new projects; explicit gives maximum control over which fields are encrypted per operation.
Setting Up the Key Vault Collection
Before encrypting any data, create a Key Vault collection — a special MongoDB collection that stores Data Encryption Keys. The key vault is just a regular collection (e.g., encryption.__keyVault) but it must have a unique index on the keyAltNames field. DEKs are stored as BSON documents with the key material encrypted by your CMK — even the key vault only stores ciphertext.
const { MongoClient, ClientEncryption } = require('mongodb-client-encryption')
// Step 1: Create key vault collection with unique index
const client = new MongoClient('mongodb://localhost:27017')
await client.connect()
const keyVaultColl = client.db('encryption').collection('__keyVault')
await keyVaultColl.createIndex(
{ keyAltNames: 1 },
{ unique: true, partialFilterExpression: { keyAltNames: { $exists: true } } }
)Creating a Data Encryption Key
Use the ClientEncryption helper to create a DEK. The key is encrypted by your CMK (here a local master key for development) and stored in the key vault. In production, replace the local provider with aws, azure, or gcp and provide the KMS credentials. You can create multiple DEKs — for example, one per tenant in a multi-tenant application.
const crypto = require('crypto')
// 96-byte local master key (development only — use KMS in production)
const localMasterKey = crypto.randomBytes(96)
const encryption = new ClientEncryption(client, {
keyVaultNamespace: 'encryption.__keyVault',
kmsProviders: { local: { key: localMasterKey } }
})
// Create a DEK with an alias for easy reference
const dataKey = await encryption.createDataKey('local', {
keyAltNames: ['userSensitiveDataKey']
})
console.log('DEK id:', dataKey)Defining the Encrypted Fields Schema
For automatic CSFLE, define an encrypted fields map that tells the driver which fields to encrypt and with which algorithm. AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic produces the same ciphertext for the same plaintext — enabling equality queries on encrypted fields. AEAD_AES_256_CBC_HMAC_SHA_512-Random produces different ciphertext each time — stronger but not queryable.
const encryptedFieldsMap = {
'myApp.users': {
fields: [
{
path: 'ssn',
bsonType: 'string',
// Deterministic: can query encrypted SSN with equality
algorithm: 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic',
keyId: dataKey
},
{
path: 'creditCardNumber',
bsonType: 'string',
// Random: cannot query, but stronger encryption
algorithm: 'AEAD_AES_256_CBC_HMAC_SHA_512-Random',
keyId: dataKey
}
]
}
}Creating an Auto-CSFLE MongoClient
To enable automatic CSFLE, configure the MongoClient with the autoEncryption option, providing the key vault namespace, KMS credentials, and the encrypted fields map. The driver will automatically encrypt matching fields on insert/update and decrypt them on read. No changes to your application queries are required.
const secureClient = new MongoClient('mongodb://localhost:27017', {
autoEncryption: {
keyVaultNamespace: 'encryption.__keyVault',
kmsProviders: { local: { key: localMasterKey } },
encryptedFieldsMap: encryptedFieldsMap
}
})
await secureClient.connect()
const users = secureClient.db('myApp').collection('users')
// SSN and creditCardNumber are auto-encrypted on insert
await users.insertOne({
name: 'Alice',
ssn: '123-45-6789', // encrypted transparently
creditCardNumber: '4111-1111-1111-1111' // encrypted transparently
})Querying Encrypted Fields
With deterministic encryption, you can perform equality queries on encrypted fields — the driver encrypts the query value with the same DEK before sending it to the server, so the server compares ciphertexts. With random encryption, equality queries are not possible because the same plaintext produces different ciphertexts each time. Range and regex queries are not supported on encrypted fields in CSFLE.
// Query an encrypted SSN field (deterministic encryption)
// The driver auto-encrypts '123-45-6789' before sending the query
const user = await users.findOne({ ssn: '123-45-6789' })
// The result has SSN decrypted automatically by the driver:
console.log(user.ssn) // '123-45-6789' (decrypted)
// A client WITHOUT the key sees ciphertext:
// user.ssn = Binary(Buffer.from('...'), 6) // encrypted blobExplicit Encryption With the Driver API
Explicit CSFLE gives you per-operation control. Call encryption.encrypt() before inserting and encryption.decrypt() after reading. This works in Community edition drivers without requiring the automatic CSFLE shared library. It is more verbose but gives complete flexibility — you can encrypt different fields in different documents with different DEKs.
// Explicit encryption
const encryptedSsn = await encryption.encrypt('123-45-6789', {
algorithm: 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic',
keyAltName: 'userSensitiveDataKey'
})
await users.insertOne({
name: 'Bob',
ssn: encryptedSsn // manually encrypted Binary value
})
// Explicit decryption
const doc = await users.findOne({ name: 'Bob' })
const decryptedSsn = await encryption.decrypt(doc.ssn)
console.log(decryptedSsn) // '123-45-6789'Key Rotation for Field-Level Encryption
Rotate DEKs periodically to limit the exposure window if a key is compromised. Key rotation in CSFLE involves creating a new DEK, re-encrypting all documents that use the old DEK (field by field), and then deleting the old DEK from the key vault. This process can be done as a background migration script without downtime. Rotating CMKs in KMS (wrapping the DEK) does not require touching the encrypted documents at all.
CSFLE Limitations and Considerations
CSFLE has important limitations to plan for: no server-side operations on encrypted fields (aggregation, sorting, and range queries on encrypted fields are not supported, except equality on deterministic fields); schema changes require DEK re-use or re-encryption; automatic CSFLE requires MongoDB Enterprise or Atlas; and performance overhead from encryption/decryption in the driver adds latency. Design your data model to minimise which fields need encryption.
Quick Check
Test your understanding of MongoDB & NoSQL Databases concepts from this lesson.
Lesson Recap
In this lesson you learned: CSFLE encrypts sensitive fields inside the driver before data reaches the server, so even MongoDB itself only sees ciphertext, deterministic encryption enables equality queries while random encryption provides stronger security without queryability, and the two-tier key model (CMK in KMS wrapping DEK in key vault) keeps encryption keys outside MongoDB. Next up we explore MongoDB schema design patterns.
常见问题解答
「客户端字段级加密」课时是免费的吗?
是的 — 「客户端字段级加密」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 MongoDB Academy 课程的其余内容,请升级到 CoddyKit PRO。 MongoDB Academy 课程共包含 4 节课。
「客户端字段级加密」这节课中我会学到什么?
学习者将配置 MongoDB 的客户端字段级加密,在敏感字段离开应用程序前对其进行加密,避免明文出现在服务器中。 你通过在浏览器中直接运行的动手代码来练习 MongoDB Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 MongoDB Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 MongoDB Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。
「客户端字段级加密」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 MongoDB Academy 课中编写并运行代码吗?
能。每节 MongoDB Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。