Docs HomeMongoDB Manual

Use Automatic Queryable Encryption with KMIP

Overview

This guide shows you how to build a Queryable Encryption (QE)-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.

Before You Get Started

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.

Tip

See: Full Application

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

Set Up the KMS

1

Configure your KMIP-Compliant Key Provider

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

Specify your Certificates

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

Create the Application

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 Your Key Vault Collection

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

Select the tab corresponding to your preferred MongoDB driver:

2

Create a Data Encryption Key

1

Add your Endpoint

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

2

Add Your Key Information

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

3

Generate your Data Encryption Keys

Tip

See: Complete Code

3

Configure the MongoClient

Tip

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

1

Specify the Key Vault Collection Namespace

Specify encryption.__keyVault as the Key Vault collection namespace.

2

Specify your KMIP Endpoint

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

3

Create an Encrypted Fields Map For Your Collection

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 Encryption Schemas guide.

4

Specify the Location of the Automatic Encryption Shared Library

5

Create the MongoClient

Instantiate a MongoDB client object with the following automatic encryption settings that use the variables declared in the previous steps:

4

Insert a Document with Encrypted Fields

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

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

{
  "_id": { "$oid": "<_id value>" },
  "firstName": "Jon",
  "lastName": "Doe",
  "patientId": {
    "$binary": {
      "base64": "<ciphertext>",
      "subType": "06"
    }
  },
  "address": "157 Electric Ave.",
  "patientRecord": {
    "ssn": {
      "$binary": {
        "base64": "<ciphertext>",
        "subType": "06"
      }
    },
    "billing": {
      "$binary": {
        "base64": "<ciphertext>",
        "subType": "06"
      }
    }
  },
  "medications": {
    "$binary": {
      "base64": "<ciphertext>",
      "subType": "06"
    }
  },
  "__safeContent__": [
    {
      "$binary": {
        "base64": "<ciphertext>",
        "subType": "00"
      }
    },
    {
      "$binary": {
        "base64": "<ciphertext>",
        "subType": "00"
      }
    }
  ]
}

Warning

Do not Modify the __safeContent__ Field

The __safeContent__ field is essential to Queryable Encryption. Do not modify the contents of this field.

Tip

See: Complete Code

5

Retrieve Your Document with Encrypted Fields

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 QE, the following code snippet queries for your document with a client configured for automatic QE as well as a client that is not configured for automatic QE.

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

Finding a document with regular (non-encrypted) client.
{
  _id: new ObjectId("628eabeb37590e84ea742665"),
  firstName: 'Jon',
  lastName: 'Doe',
  patientId: new Binary(Buffer.from("0798810acc0f4f46c9a76883cee80fca12102e9ddcbcdae46a821fa108a8155a850f2d0919475b6531ada68973d436a199b537a05a98a708c36d2bfec4979d59cbe66878865ce19e392d3e4789d309bdacc336e32efcc851806ae0a41b355288c10d01e39147e1c40d919c41913a0c9d2d3fad0d0d1d2873c4fc82c6c22f27b517df5f3131b331b96ed16a7c5cf89e09082a2d898c2dcd73da91d08760ba74a70077b2d0fdbbe1eea75655a19fcc397812325ad40b102cbd16b8d36b22e11e3f93404f24a8ff68cfdec3c22b0e787cb30078a5227b2a", "hex"), 6),
  address: '157 Electric Ave.',
  patientRecord: {
    ssn: new Binary(Buffer.from("07e8b69630c32f4a00a542af768f8abcf50223edd812ff20b0ecb046ee1a9f5a0eef8d85d99cd26076411129942752516ee605c55aadce73f3d44d81ea6ddbbb8134b108a9deb40d8cab9cb4f08ef210ab0c9d2ea4347f9d235b861baf29751e60abcf059eb5c120305bd5ac05a4e07ac8ccfa6d37283f4cdbfeb7a8accb65b71857d486b5cf55e354d6a95e287d9e2dd65f3f9d9c4c9d0bdb1f26c4bd549d7be77db81796be293e08b2223bac67b212423c4e06568578b5bd7a3c33cedc1b291bcda0b27e005144d344563711a489f24b8e9b65bbb721d3a0e9d9b227a0cec0cbad", "hex"), 6),
    billing: new Binary(Buffer.from("06808ae69d4caa49cf90bb688f386f097f03f870a7b8fcebb1980c9ee5488b1f0f68558fc2163adcd92d00ea5f349f56ed34e7b391f54c48ed2760b4bde73022fc818dc7486a4e046b92ce9c82e00333c7779d9d6bb476713a20632b593b7de54812662cfc4d174d05451d3f4195514e12edba", "hex"), 6)
  },
  medications: new Binary(Buffer.from("06665ec15d38254dc4aa16da856789d33404f27bfea53e0d2fa4deaff166989ab33f469644d89c29112d33b41dbe54ec2d89c43f3de52cdc5d454e8694046216f533614fa7b42b7c5406d6518f7ed8f9e3ce52fda6c8b2146d0f8cc51e21a3467183697e1735a9f60c18e173c1916101", "hex"), 6),
  __safeContent__: [
    new Binary(Buffer.from("3044b134ad0f7c8a90dab1e05bb8b296a8ede540796bd7403ab47693cdba1b26", "hex"), 0),
    new Binary(Buffer.from("a22ddf9a5657cdd56bef72febbba44371899e6486962a1c07d682082c4e65712", "hex"), 0)
  ]
}
Finding a document with encrypted client, searching on an encrypted field
{
  _id: new ObjectId("628eaca1dcf9b63e2f43162d"),
  firstName: 'Jon',
  lastName: 'Doe',
  patientId: 12345678,
  address: '157 Electric Ave.',
  patientRecord: {
    ssn: '987-65-4320',
    billing: { type: 'Visa', number: '4111111111111111' }
  },
  medications: [ 'Atorvastatin', 'Levothyroxine' ],
  __safeContent__: [
    new Binary(Buffer.from("fbdc6cfe3b4659693650bfc60baced27dcb42b793efe09da0ded54d60a9d5a1f", "hex"), 0),
    new Binary(Buffer.from("0f92ff92bf904a858ef6fd5b1e508187f523e791f51d8b64596461b38ebb1791", "hex"), 0)
  ]
}

Tip

See: Complete Code

Learn More

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