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.

Use Automatic Client-Side Field Level Encryption with KMIP

This guide shows you how to build a Client-Side Field Level Encryption (CSFLE)-enabled application using a Key Management Interoperability Protocol (KMIP)-compliant key provider.

After you complete the steps in this guide, you should have:

  • A Customer Master Key hosted on a KMIP-compliant key provider.

  • A working client application that inserts documents with encrypted fields using your Customer Master Key.

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

Throughout this guide, code examples use placeholder text. Before you run the examples, substitute your own values for these placeholders.

For example:

dek_id := "<Your Base64 DEK ID>"

You would replace everything between quotes with your DEK ID.

dek_id := "abc123"

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.

Note

mongod reads the KMIP configuration at startup. By default, the server uses KMIP protocol version 1.2.

To connect to a version 1.0 or 1.1 KMIP server, use the useLegacyProtocol setting.

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

To connect a MongoDB driver client to your KMIP-compliant key provider, you must configure your KMIP-compliant key provider such that it accepts your client's TLS certificate.

Consult the documentation for your KMIP-compliant key provider for information on how to accept your client certificate.

2

Your client must connect to your KMIP-compliant key provider through TLS and present a client certificate that your KMIP-compliant key provider accepts:

var tlsOptions = new Dictionary<string, SslSettings>();var sslSettings = new SslSettings();var clientCertificate = new X509Certificate2("<path to your pkcs12 client certificate file>");sslSettings.ClientCertificates = new List<X509Certificate>() { clientCertificate, };tlsOptions.Add(provider, sslSettings);

Important

Your client certificate must be in pkcs12 format. You can convert your certificate using your certificate using OpenSSL with the following command:

openssl pkcs12 -export -out "<new pkcs12 certificate>" -in "<certificate to convert>" \-name "<new certificate name>" -password "<new certificate password>"

Select the tab that corresponds to the MongoDB driver you are using in your application to see relevant code samples.

1

Create a unique index on the keyAltNames field in your encryption.__keyVault namespace.

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);
2
  1. Add your Endpoint

    Specify the URI endpoint of your KMIP-compliant key provider:

    var kmsProviders = new Dictionary<string, IReadOnlyDictionary<string, object>>();var provider = "kmip";var kmipKmsOptions = new Dictionary<string, object>{ { "endpoint", "<endpoint for your KMIP-compliant key provider>" },};kmsProviders.Add(provider, kmipKmsOptions);
  2. Add Your Key Information

    The following code prompts your KMIP-compliant key provider to automatically generate a Customer Master Key:

    var dataKeyOptions = new DataKeyOptions( masterKey: new BsonDocument { } // an empty key object prompts your KMIP-compliant key provider to generate a new Customer Master Key);
  3. Generate your Data Encryption Key

    Generate your Data Encryption Key using the variables declared in step one of this tutorial.

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

Tip

See: Complete Code

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

3

Tip

Follow the remaining steps in this tutorial in a separate file from the one created in the previous steps.

To view the complete code for this file, see our Github repository

  1. Specify the Key Vault Collection Namespace

    Specify encryption.__keyVault as the Key Vault collection namespace.

    var keyVaultNamespace = CollectionNamespace.FromFullName("encryption.__keyVault");
  2. Specify your KMIP Endpoint

    Specify kmip in your kmsProviders object and enter the URI endpoint of your KMIP-compliant key provider:

    var kmsProviders = new Dictionary<string, IReadOnlyDictionary<string, object>>();var provider = "kmip";var kmipKmsOptions = new Dictionary<string, object>{ { "endpoint", "<endpoint for your KMIP-compliant key provider>" },};kmsProviders.Add(provider, kmipKmsOptions);
  3. Create an Encryption Schema For Your Collection

    Create an encryption schema that specifies how your client application encrypts your documents' fields:

    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);

    Tip

    Further Reading on Schemas

    To view an in-depth description of how to construct the schema you use in this step, see the Encryption Schemas guide.

    To view a list of all supported encryption rules for your encryption schemas, see the CSFLE Encryption Schemas guide.

  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 that use the variables declared in the previous steps:

    MongoClientSettings.Extensions.AddAutoEncryption(); // .NET/C# Driver v3.0 or later onlyvar clientSettings = MongoClientSettings.FromConnectionString(connectionString);var autoEncryptionOptions = new AutoEncryptionOptions( keyVaultNamespace: keyVaultNamespace, kmsProviders: kmsProviders, schemaMap: schemaMap, extraOptions: extraOptions, tlsOptions: tlsOptions );clientSettings.AutoEncryptionOptions = autoEncryptionOptions;var secureClient = new MongoClient(clientSettings);
4

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

5

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 inserting a document with encrypted fields, see our Github repository

To learn how CSFLE works, see CSFLE Fundamentals.

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