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.
Docs Menu

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.

To see the complete code for the sample application, select your programming language in the language selector.

// 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

Secure your Local Key File in Production

We recommend storing your Customer Master Keys in a remote Key Management System (KMS). To learn how to use a remote KMS in your Queryable Encryption implementation, see the Queryable Encryption Tutorials guide.

If you choose to use a local key provider in production, exercise great caution and do not store it on the file system. Consider injecting the key into your client application using a sidecar process, or use another approach that keeps the key secure.

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
  1. Read the Customer Master Key and Specify KMS Provider Settings

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

    Use the CMK value in 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);
  2. Create a Data Encryption Key

    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
  1. Specify the Key Vault Collection Namespace

    Specify encryption.__keyVault as the Key Vault collection namespace.

    var keyVaultNamespace = CollectionNamespace.FromFullName("encryption.__keyVault");
  2. Specify the Local Customer Master Key

    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);
  3. Create an Encryption Schema For Your Collection

    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);
  4. Specify the Location of the Automatic Encryption Shared Library

    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 Install and Configure a CSFLE Query Analysis Component page.

  5. Create the MongoClient

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

    MongoClientSettings.Extensions.AddAutoEncryption(); // .NET/C# Driver v3.0 or later only
    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 client
var secureCollection = secureClient.GetDatabase(db).GetCollection<BsonDocument>(coll);
// Insert a document into the collection
secureCollection.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");
var ssnFilter = Builders<BsonDocument>.Filter.Eq("name", "Jon Doe");
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
{
_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: