- Reference
- Client Side Encryption
Client Side Encryption
New in MongoDB 4.2 client side encryption allows administrators and developers to encrypt specific data fields in addition to other MongoDB encryption features.
With field level encryption, developers can encrypt fields client side without any server-side configuration or directives. Client-side field level encryption supports workloads where applications must guarantee that unauthorized parties, including server administrators, cannot read the encrypted data.
Installation
Using client side encryption requires installing themongodb-client-encryption
package:
npm install mongodb-client-encryption
Prebuilds and manual compilation
mongodb-client-encryption
has dependencies on the libbson
and libmongocrypt
C libraries, which means that a C++ toolchain is required in
order to build the addon. In order to improve user experience we have leveraged the prebuild
package
to pre-compile the module during CI, so that in most cases you should be able to automatically install a pre-built version without needing to
compile anything. However, if you are running on an architecture we have not created a prebuild for, or if you need to install without
network access to github.com, you will need to manually build and compile these dependencies. Follow the instructions here for more information.
mongocryptd configuration
Client encryption requires the mongocryptd
to function correctly. If the process has not started before encryption is requested, the driver
will attempt to auto-spawn a mongocrypt
instance. This means that mongocrypt
should be in your PATH before running your application. You
can also configure the driver to use an alternate URI to connect by setting the autoEncryption.extraOptions.mongocryptdURI
to a valid
connection string. There are more details on these options in the API documentation.
Examples
The following is a sample app that assumes the key and schema have already been created in MongoDB. The example uses a local key,
however using AWS Key Management Service is also an option. The data in the encryptedField
field is automatically encrypted on the
insert and decrypted when using find on the client side.
const { MongoClient } = require('mongodb');
const crypto = require('crypto');
// This would have to be the same master key as was used to create the encryption key
const localMasterKey = crypto.randomBytes(96);
const autoEncryption = {
keyVaultNamespace: 'admin.datakeys',
kmsProviders: {
local: {
key: localMasterKey
}
}
};
const URL = 'mongodb://localhost:27017';
const client = new MongoClient(URL, { autoEncryption, useUnifiedTopology: true });
main();
async function main() {
try {
await client.connect();
const db = mongoClient.db('test');
await db.dropCollection('coll');
const collection = db.collection('coll');
await collection.insertOne({ encryptedField: '123456789' });
const result = await collection.findOne({});
console.log(result);
} finally {
await client.close();
}
}
Note
Auto encryption is an enterprise only feature.
The following example shows how to leverage a ClientEncryption
instance to create a new key and use that key in the json schema map.
const crypto = require('crypto');
const { MongoClient } = require('mongodb');
const { ClientEncryption } = require('mongodb-client-encryption');
const keyVaultNamespace = 'admin.datakeys';
// This would have to be the same master key as was used to create the encryption key
const localMasterKey = crypto.randomBytes(96);
const kmsProviders = { local: { key: localMasterKey } };
const URL = 'mongodb://localhost:27017';
main();
async function main() {
const unencryptedClient = new MongoClient(URL, { useUnifiedTopology: true });
try {
await unencryptedClient.connect();
const clientEncryption = new ClientEncryption(unencryptedClient, { kmsProviders, keyVaultNamespace });
const dataKeyId = await clientEncryption.createDataKey('local');
const dbName = 'test';
const collName = 'coll';
const schemaMap = {
[`${dbName}.${collName}`]: {
properties: {
encryptedField: {
encrypt: {
keyId: [ dataKeyId ],
bsonType: 'string',
algorithm: 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'
}
}
}
}
};
const encryptedClient = new MongoClient(URL, {
useUnifiedTopology: true,
autoEncryption: {
keyVaultNamespace,
kmsProviders,
schemaMap
}
});
try {
await encryptedClient.connect();
// Do stuff here
} finally {
await encryptedClient.close();
}
} finally {
await unencryptedClient.close();
}
}