For AI agents: a documentation index is available at https://www.mongodb.com/docs/llms.txt — markdown versions of all pages are available by appending .md to any URL path.

CSFLE Quick Start

This guide shows you how to encrypt a document with automatic Client-Side Field Level Encryption (CSFLE) and a MongoDB driver.

After completing this guide, you should have the following knowledge and software:

  • Knowledge of the steps to configure a driver to encrypt fields in a document.

  • A working, but not production-ready, client application that utilizes automatic Client-Side Field Level Encryption.

Important

Do Not Use this Application In Production

Since this example application stores an encryption key on your application's filesystem, you risk unauthorized access to the key or loss of the key to decrypt your data.

To view a tutorial that demonstrates how to create a production-ready CSFLE-enabled application, see CSFLE Tutorials.

To complete and run the code in this guide, you need to set up your development environment as shown in the Installation Requirements page.

Select the programming language for which you want to see code examples for from the Select your language dropdown menu on the right side of the page.

Tip

See: Full Application

To view the complete runnable application code for this tutorial, go to the following link:

// You are viewing the .NET/C# driver code examples.// Use the dropdown menu to select a different driver.
1

You must create a Customer Master Key (CMK) to perform CSFLE.

Create a 96-byte Customer Master Key and save it in your Local Key Provider, which is your filesystem, as the file master-key.txt:

const fs = require("fs");const crypto = require("crypto");try { fs.writeFileSync("master-key.txt", crypto.randomBytes(96));} catch (err) { console.error(err);}

Warning

Do Not Use the Local Key Provider in Production

The Local Key Provider is an insecure method of storage and is not recommended for production. Instead, you should store your Customer Master Keys in a remote Key Management System (KMS).

To learn how to use a remote KMS in your CSFLE implementation, see the CSFLE Tutorials guide.

Tip

Generate a CMK from the Command Line

Use the following command to generate a CMK from a Unix shell or PowerShell:

  • Unix/macOS shell:

    echo $(head -c 96 /dev/urandom | base64 | tr -d '\n')
  • PowerShell:

    $r=[byte[]]::new(64);$g=[System.Security.Cryptography.RandomNumberGenerator]::Create();$g.GetBytes($r);[Convert]::ToBase64String($r)

Save the output of the preceding command to a file named customer-master-key.txt.

Tip

See: Complete Code

To view the complete code for making a Customer Master Key, see our Github repository.

2

Create a partial unique index on the keyAltNames field in your encryption.__keyVault namespace. This index should have a partialFilterExpression for documents where keyAltNames exists.

Client-Side Field Level Encryption depends on server-enforced uniqueness of key alternate names.

Select the tab corresponding to your preferred MongoDB driver:

var connectionString = "<Your MongoDB URI>";var keyVaultNamespace = CollectionNamespace.FromFullName("encryption.__keyVault");var keyVaultClient = new MongoClient(connectionString);var indexOptions = new CreateIndexOptions<BsonDocument>();indexOptions.Unique = true;indexOptions.PartialFilterExpression = new BsonDocument { { "keyAltNames", new BsonDocument { { "$exists", new BsonBoolean(true) } } } };var builder = Builders<BsonDocument>.IndexKeys;var indexKeysDocument = builder.Ascending("keyAltNames");var indexModel = new CreateIndexModel<BsonDocument>(indexKeysDocument, indexOptions);var keyVaultDatabase = keyVaultClient.GetDatabase(keyVaultNamespace.DatabaseNamespace.ToString());// Drop the Key Vault Collection in case you created this collection// in a previous run of this application. keyVaultDatabase.DropCollection(keyVaultNamespace.CollectionName);// Drop the database storing your encrypted fields as all// the DEKs encrypting those fields were deleted in the preceding line.keyVaultClient.GetDatabase("medicalRecords").DropCollection("patients");var keyVaultCollection = keyVaultDatabase.GetCollection<BsonDocument>(keyVaultNamespace.CollectionName.ToString());keyVaultCollection.Indexes.CreateOne(indexModel);
3

Retrieve the contents of the Customer Master Key file that you generated in the Create a Customer Master Key step of this guide.

Pass the CMK value to your KMS provider settings. The client uses these settings to discover the CMK. As you are using the Local Key Provider, set the provider name to local.

var kmsProviders = new Dictionary<string, IReadOnlyDictionary<string, object>>();var provider = "local";string localMasterKeyBase64Read = File.ReadAllText("master-key.txt");var localMasterKeyBytes = Convert.FromBase64String(localMasterKeyBase64Read);var localOptions = new Dictionary<string, object>{ { "key", localMasterKeyBytes }};kmsProviders.Add("local", localOptions);

Construct a client with your MongoDB connection string and Key Vault collection namespace, and create a Data Encryption Key:

Note

Key Vault Collection Namespace Permissions

To complete this tutorial, the database user your application uses to connect to MongoDB must have dbAdmin permissions on the following namespaces:

  • encryption.__keyVault

  • medicalRecords database

var clientEncryptionOptions = new ClientEncryptionOptions( keyVaultClient: keyVaultClient, keyVaultNamespace: keyVaultNamespace, kmsProviders: kmsProviders ); var clientEncryption = new ClientEncryption(clientEncryptionOptions);var dataKeyOptions = new DataKeyOptions();var dataKeyId = clientEncryption.CreateDataKey(provider, dataKeyOptions, CancellationToken.None);var dataKeyIdBase64 = Convert.ToBase64String(GuidConverter.ToBytes(dataKeyId, GuidRepresentation.Standard));Console.WriteLine($"DataKeyId [base64]: {dataKeyIdBase64}");

The output from the code above should resemble the following:

DataKeyId [base64]: 3k13WkSZSLy7kwAAP4HDyQ==

Tip

See: Complete Code

To view the complete code for making a Data Encryption Key, see our Github repository.

4

Specify encryption.__keyVault as the Key Vault collection namespace.

var keyVaultNamespace = CollectionNamespace.FromFullName("encryption.__keyVault");

Specify the KMS provider and specify your key inline:

var kmsProviders = new Dictionary<string, IReadOnlyDictionary<string, object>>();var provider = "local";var localMasterKeyPath = "master-key.txt";string localMasterKeyBase64Read = File.ReadAllText(localMasterKeyPath);var localMasterKeyBytes = Convert.FromBase64String(localMasterKeyBase64Read);var localOptions = new Dictionary<string, object>{ { "key", localMasterKeyBytes }};kmsProviders.Add(provider, localOptions);

Tip

Add Your Data Encryption Key Base64 ID

Make sure to update the following code to include your Base64 DEK ID. You received this value in the Generate your Data Encryption Key step of this guide.

var keyId = "<Your base64 DEK ID here>";var schema = new BsonDocument{ { "bsonType", "object" }, { "encryptMetadata", new BsonDocument("keyId", new BsonArray(new[] { new BsonBinaryData(Convert.FromBase64String(keyId), BsonBinarySubType.UuidStandard) })) }, { "properties", new BsonDocument { { "ssn", new BsonDocument { { "encrypt", new BsonDocument { { "bsonType", "int" }, { "algorithm", "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" } } } } }, { "bloodType", new BsonDocument { { "encrypt", new BsonDocument { { "bsonType", "string" }, { "algorithm", "AEAD_AES_256_CBC_HMAC_SHA_512-Random" } } } } }, { "medicalRecords", new BsonDocument { { "encrypt", new BsonDocument { { "bsonType", "array" }, { "algorithm", "AEAD_AES_256_CBC_HMAC_SHA_512-Random" } } } } }, { "insurance", new BsonDocument { { "bsonType", "object" }, { "properties", new BsonDocument { { "policyNumber", new BsonDocument { { "encrypt", new BsonDocument { { "bsonType", "int" }, { "algorithm", "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" } } } } } } } } } } }};var schemaMap = new Dictionary<string, BsonDocument>();schemaMap.Add(dbNamespace, schema);
var mongoBinariesPath = "<Full path to your Automatic Encryption Shared Library>";var extraOptions = new Dictionary<string, object>(){ { "cryptSharedLibPath", mongoBinariesPath },};

Note

Automatic Encryption Options

The automatic encryption options provide configuration information to the Automatic Encryption Shared Library, which modifies the application's behavior when accessing encrypted fields.

To learn more about the Automatic Encryption Shared Library, see the Automatic Encryption Shared Library for CSFLE page.

Instantiate a MongoDB client object with the following automatic encryption settings:

var clientSettings = MongoClientSettings.FromConnectionString(connectionString);var autoEncryptionOptions = new AutoEncryptionOptions( keyVaultNamespace: keyVaultNamespace, kmsProviders: kmsProviders, schemaMap: schemaMap, extraOptions: extraOptions );clientSettings.AutoEncryptionOptions = autoEncryptionOptions;var secureClient = new MongoClient(clientSettings);
5

Use your CSFLE-enabled MongoClient instance to insert a document with encrypted fields into the medicalRecords.patients namespace using the following code snippet:

var sampleDocFields = new BsonDocument{ { "name", "Jon Doe" }, { "ssn", 145014000 }, { "bloodType", "AB-" }, { "medicalRecords", new BsonArray { new BsonDocument("weight", 180), new BsonDocument("bloodPressure", "120/80") } }, { "insurance", new BsonDocument { { "policyNumber", 123142 }, { "provider", "MaestCare" } } }}; // Construct an auto-encrypting clientvar secureCollection = secureClient.GetDatabase(db).GetCollection<BsonDocument>(coll); // Insert a document into the collectionsecureCollection.InsertOne(sampleDocFields);

When you insert a document, your CSFLE-enabled client encrypts the fields of your document such that it resembles the following:

{ "_id": { "$oid": "<_id of your document>" }, "name": "Jon Doe", "ssn": { "$binary": "<cipher-text>", "$type": "6" }, "bloodType": { "$binary": "<cipher-text>", "$type": "6" }, "medicalRecords": { "$binary": "<cipher-text>", "$type": "6" }, "insurance": { "provider": "MaestCare", "policyNumber": { "$binary": "<cipher-text>", "$type": "6" } }}

Tip

See: Complete Code

To view the complete code for inserting a document with encrypted fields, see our Github repository

6

Retrieve the document with encrypted fields you inserted in the Insert a Document with Encrypted Fields step of this guide.

To show the functionality of CSFLE, the following code snippet queries for your document with a client configured for automatic CSFLE as well as a client that is not configured for automatic CSFLE.

Console.WriteLine("Finding a document with regular (non-encrypted) client.");var filter = Builders<BsonDocument>.Filter.Eq("name", "Jon Doe");var regularResult = regularCollection.Find(filter).Limit(1).ToList()[0];Console.WriteLine($"\n{regularResult}\n"); Console.WriteLine("Finding a document with encrypted client, searching on an encrypted field");var ssnFilter = Builders<BsonDocument>.Filter.Eq("ssn", 145014000);var secureResult = secureCollection.Find(ssnFilter).Limit(1).First();Console.WriteLine($"\n{secureResult}\n");

The output of the preceding code snippet should look like this:

Finding a document with regular (non-encrypted) client. { _id: new ObjectId("629a452e0861b3130887103a"), name: 'Jon Doe', ssn: new Binary(Buffer.from("0217482732d8014cdd9ffdd6e2966e5e7910c20697e5f4fa95710aafc9153f0a3dc769c8a132a604b468732ff1f4d8349ded3244b59cbfb41444a210f28b21ea1b6c737508d9d30e8baa30c1d8070c4d5e26", "hex"), 6), bloodType: new Binary(Buffer.from("0217482732d8014cdd9ffdd6e2966e5e79022e238536dfd8caadb4d7751ac940e0f195addd7e5c67b61022d02faa90283ab69e02303c7e4001d1996128428bf037dea8bbf59fbb20c583cbcff2bf3e2519b4", "hex"), 6), 'key-id': 'demo-data-key', medicalRecords: new Binary(Buffer.from("0217482732d8014cdd9ffdd6e2966e5e790405163a3207cff175455106f57eef14e5610c49a99bcbd14a7db9c5284e45e3ee30c149354015f941440bf54725d6492fb3b8704bc7c411cff6c868e4e13c58233c3d5ed9593eca4e4d027d76d3705b6d1f3b3c9e2ceee195fd944b553eb27eee69e5e67c338f146f8445995664980bf0", "hex"), 6), insurance: { policyNumber: new Binary(Buffer.from("0217482732d8014cdd9ffdd6e2966e5e79108decd85c05be3fec099e015f9d26d9234605dc959cc1a19b63072f7ffda99db38c7b487de0572a03b2139ac3ee163bcc40c8508f366ce92a5dd36e38b3c742f7", "hex"), 6), provider: 'MaestCare' }} Finding a document with encrypted client, searching on an encrypted field { _id: new ObjectId("629a452e0861b3130887103a"), name: 'Jon Doe', ssn: 241014209, bloodType: 'AB+', 'key-id': 'demo-data-key', medicalRecords: [ { weight: 180, bloodPressure: '120/80' } ], insurance: { policyNumber: 123142, provider: 'MaestCare' }}

Tip

See: Complete Code

To view the complete code for finding a document with encrypted fields, see our Github repository

To view a tutorial on production-ready CSFLE with a remote KMS, see CSFLE Tutorials.

To learn how CSFLE works, see CSFLE Fundamentals.

To learn more about the topics mentioned in this guide, see the following links: