Data encryption (field-level encryption, storage encryption)
Basic Concepts of Data Encryption
Data encryption is a crucial means of protecting sensitive information, especially in database systems. MongoDB offers various encryption methods, including field-level encryption and storage encryption. Field-level encryption allows specific fields to be encrypted, while storage encryption encrypts the entire database file. These two methods can be used independently or in combination to meet security requirements in different scenarios.
Field-Level Encryption
Field-Level Encryption refers to encrypting specific fields within a document while leaving other fields in plaintext. This approach is suitable for handling documents containing sensitive information, such as user passwords, ID numbers, or credit card numbers.
Client-Side Field-Level Encryption
MongoDB 4.2 introduced Client-Side Field-Level Encryption (CSFLE), which allows fields to be encrypted before the data is sent to the server. This ensures that sensitive data remains encrypted during both transmission and storage.
const { MongoClient, ClientEncryption } = require('mongodb');
const { Binary } = require('mongodb');
const keyVaultNamespace = 'encryption.__keyVault';
const kmsProviders = {
local: {
key: Buffer.from('your-32-byte-key-here', 'hex')
}
};
const client = new MongoClient('mongodb://localhost:27017');
const encryption = new ClientEncryption(client, {
keyVaultNamespace,
kmsProviders
});
async function encryptField() {
const dataKey = await encryption.createDataKey('local');
const encryptedValue = await encryption.encrypt('Sensitive Data', {
keyId: dataKey,
algorithm: 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'
});
await client.db('test').collection('users').insertOne({
name: 'John Doe',
ssn: encryptedValue
});
}
encryptField();
Automatic Encryption
MongoDB drivers support automatic encryption by defining a JSON Schema to specify which fields should be encrypted:
const schema = {
'bsonType': 'object',
'properties': {
'ssn': {
'encrypt': {
'bsonType': 'string',
'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic',
'keyId': [dataKey]
}
}
}
};
const client = new MongoClient('mongodb://localhost:27017', {
autoEncryption: {
keyVaultNamespace,
kmsProviders,
schemaMap: {
'test.users': schema
}
}
});
Storage Encryption
Storage Encryption refers to encrypting the entire database file, including data files, log files, and temporary files. MongoDB Enterprise Edition provides native encryption capabilities.
WiredTiger Encryption
MongoDB Enterprise Edition supports encryption-at-rest for the WiredTiger storage engine:
mongod --enableEncryption --encryptionKeyFile /path/to/keyfile
The keyfile is a file containing a hexadecimal string used to encrypt the database files. For example:
1234567890abcdef1234567890abcdef
Key Management
MongoDB supports multiple key management methods:
- Local keyfile (as shown above)
- KMIP (Key Management Interoperability Protocol) server
- AWS KMS (Key Management Service)
- Azure Key Vault
Example configuration using KMIP:
security:
enableEncryption: true
kmip:
serverName: kmip.example.com
port: 5696
clientCertificateFile: /path/to/client.pem
clientCertificatePassword: password
serverCAFile: /path/to/ca.pem
Encryption Algorithm Comparison
MongoDB supports various encryption algorithms for different scenarios:
Algorithm | Type | Characteristics | Use Case |
---|---|---|---|
AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic | Field Encryption | Same input produces same output | Supports equality queries |
AEAD_AES_256_CBC_HMAC_SHA_512-Random | Field Encryption | Different output for each encryption | Highest security |
AES256-GCM | Storage Encryption | Block encryption | WiredTiger encryption |
Performance Considerations
Encryption operations introduce some performance overhead:
- Field-level encryption increases client CPU usage.
- Storage encryption increases storage space by approximately 5-15%.
- Encrypted queries may not utilize certain indexes.
It is recommended to conduct benchmarks for performance-sensitive applications, such as:
// Performance test example
async function testEncryptionPerformance() {
const start = Date.now();
for (let i = 0; i < 1000; i++) {
await collection.insertOne({
name: `User${i}`,
ssn: await encryption.encrypt(`123-45-${1000 + i}`, {
keyId: dataKey,
algorithm: 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'
})
});
}
console.log(`Time taken: ${Date.now() - start}ms`);
}
Best Practices
- Classify data sensitivity levels and encrypt only truly sensitive fields.
- Rotate encryption keys periodically.
- Separate key management from the database.
- Test query performance after encryption.
- Log all encryption operations.
Example of key rotation:
async function rotateKey() {
const newKey = await encryption.createDataKey('local');
await client.db('test').collection('users').updateMany(
{},
[{
$set: {
ssn: {
$convert: {
input: "$ssn",
to: "string"
}
}
}
}]
);
// Re-encrypt using the new key
const cursor = client.db('test').collection('users').find();
while (await cursor.hasNext()) {
const doc = await cursor.next();
const encrypted = await encryption.encrypt(doc.ssn, {
keyId: newKey,
algorithm: 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'
});
await client.db('test').collection('users').updateOne(
{ _id: doc._id },
{ $set: { ssn: encrypted } }
);
}
}
Security Auditing
After implementing encryption, establish an auditing mechanism:
- Log key access.
- Monitor abnormal encryption/decryption operations.
- Regularly review encryption configurations.
Example audit configuration:
auditLog:
destination: file
format: JSON
path: /var/log/mongodb/audit.json
filter:
'$or': [
{ 'atype': 'authenticate' },
{ 'atype': 'createUser' },
{ 'atype': 'dropUser' },
{ 'atype': 'grantRoles' },
{ 'atype': 'revokeRoles' },
{ 'atype': 'createCollection', 'param.ns': /\.system\.keys$/ }
]
Integration with Other Security Measures
Data encryption should be part of a comprehensive security strategy:
- Combine with TLS/SSL to protect data in transit.
- Implement Role-Based Access Control (RBAC).
- Enable network isolation.
- Conduct regular security assessments.
RBAC example:
use admin
db.createRole({
role: "encryptedDataReader",
privileges: [{
resource: { db: "test", collection: "users" },
actions: ["find"]
}],
roles: []
})
db.createUser({
user: "reader",
pwd: "securepassword",
roles: ["encryptedDataReader"]
})
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
上一篇:加密传输(TLS/SSL)
下一篇:审计日志(Audit Log)