Docs HomeMongoDB Manual

Quick Start

Overview

This guide shows you how to encrypt a document with automatic Queryable Encryption 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 Queryable 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 Queryable Encryption enabled application that uses a remote Key Management System, see Tutorials.

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.

Tip

See: Full Application

To see the complete code for the application you make in this guide, select the tab corresponding to your programming language and follow the provided link:

Procedure

1

Create a Customer Master Key

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

Create a 96-byte Customer Master Key and save it to your filesystem, as the file master-key.txt:

Warning

Do Not Use a Local Key File in Production

A local key file in your filesystem is insecure 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 Queryable Encryption implementation, see the Tutorials guide.

Note

Generate a CMK from the Command Line

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

  • Unix 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 master-key.txt.

Tip

See: Complete Code

2

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:

3

Create your Data Encryption Keys and Encrypted Collection

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.

Pass the CMK value to your KMS provider settings. The client uses these settings to discover the CMK. Set the provider name to local to inform the driver you are using a Local Key Provider.

Select the tab corresponding to your preferred MongoDB driver:

2

Create your Data Encryption Keys

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

Note

Key Vault Collection Namespace Permissions

The Key Vault collection is in the encryption.__keyVault namespace. Ensure that the database user your application uses to connect to MongoDB has ReadWrite permissions on this namespace.

3

Create Your Encrypted Collection

Use a Queryable Encryption enabled MongoClient instance to specify what fields you must encrypt and create your encrypted collection:

The output from the code in this section should resemble the following:

Created encrypted collection!

Tip

See: Complete Code

4

Configure your MongoClient for Encrypted Reads and Writes

1

Specify the Key Vault Collection Namespace

Specify encryption.__keyVault as the Key Vault collection namespace.

2

Specify the Local Customer Master Key

Specify the KMS provider and specify your Customer Master Key inline:

3

Create an Encrypted Fields Map For Your Collection

4

Specify the Location of the Automatic Encryption Shared Library

Tip

Learn More

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

5

Create the MongoClient

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

5

Insert a Document with Encrypted Fields

Use your Queryable Encryption 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

6

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

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 view a tutorial on production-ready Queryable Encryption with a remote KMS, see Tutorials.

To learn how Queryable Encryption works, see Fundamentals.

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

  • Learn more about Queryable Encryption components on the Reference page.

  • Learn how Customer Master Keys and Data Encryption Keys work on the Keys and Key Vaults page.

  • See how KMS Providers manage your Queryable Encryption keys on the KMS Providers page.