Using Fortanix Data Security Manager for MongoDB Client-Side Field-Level Encryption

1.0 Introduction

This article describes how to integrate Fortanix-Data-Security-Manager (DSM) with the MongoDB Client-Side Field-Level Encryption (CSFLE) to securely manage encryption keys and protect sensitive data before storing it in MongoDB.

CSFLE ensures that data is encrypted on the client-side before being sent to the database, so MongoDB never has access to unencrypted data. In MongoDB Enterprise, a master key is the encryption keys. It encrypts the DEK which is used to encrypt required fields in a client-side document.

By default, this master key is created by the libmongocryptd library as a 96-byte secret and stored in an external Key Management System (KMS). To enhance security, Fortanix DSM can generate and store the master key inside DSM itself as a 96-byte SECRET type security object, ensuring it never exists outside DSM.

With Key Management Interoperability Protocol (KMIP) support, Fortanix DSM offers a secure and flexible way to generate and manage encryption keys, providing strong data protection for MongoDB deployments.

2.0 Prerequisites

Ensure the following:

  • MongoDB Enterprise version 4.2 or later is installed.

  • Ensure that the GitHub repository is cloned into your environment. This repository contains the sample Java application to configure MongoDB CSFLE with Fortanix DSM.

  • Administrator access to the Fortanix DSM. For more information, refer to Section 5.1: Signing Up and Section 5.2: Creating an Account.

3.0 Product Tested Version

This integration has been tested on the following versions:

  • Fortanix DSM version 4.35

  • MongoDB Enterprise version 8.0.4

  • MongoDB Java Driver version 5.0.0

  • MongoDB Crypt version 1.8.0

  • Mongosh version 2.3.7

4.0 Architecture Diagram

Figure 1: Architecture Diagram of Fortanix DSM with MongoDB CSFLE

This diagram illustrates the integration of MongoDB CSFLE with Fortanix DSM for secure encryption key management using the Key Management Interoperability Protocol (KMIP).

MongoDB CSFLE ensures that sensitive data is encrypted on the client side before being sent to the database, ensuring that MongoDB never processes unencrypted data. Fortanix DSM securely generates, stores, and manages encryption keys, ensuring encryption and decryption operations remain secure and controlled.

When a client application needs to encrypt data, it requests a master key from Fortanix DSM using the KMIP provider. Instead of generating the master key locally, the Fortanix DSM plugin creates a 96-byte secret inside DSM. This ensures that the master key is never exposed outside DSM, reducing security risks.

Once the master key is available, libmongocryptd generates a Data Encryption Key (DEK), which encrypts specific fields in the client’s document before insertion into MongoDB. The DEK is itself encrypted using the master key and stored securely in the MongoDB Key Vault collection. Along with the encrypted DEK, MongoDB stores a unique Base64-encoded ID, which serves as a reference for retrieving the DEK when needed.

When a client requests to decrypt a document, MongoDB retrieves the encrypted DEK from the Key Vault collection using its Base64-encoded ID and contacts Fortanix DSM using KMIP to access the master key required to decrypt the DEK. Once decrypted, the DEK is used to decrypt the specific fields in the document so that the sensitive information is accessible only to authorized applications.

KMIP plays a crucial role by standardizing secure communication between MongoDB encryption libraries and Fortanix DSM by allowing automated key retrieval, storage, and rotation without manual intervention.

In the event of a MongoDB breach, attackers cannot access plaintext data because encryption keys are stored separately in Fortanix DSM. Even if an attacker gains access to the Base64-encoded DEK ID, they cannot decrypt the data without the master key, which remains securely managed by Fortanix DSM.

This integration provides strong encryption, centralized key management, and enhanced security compliance, making Fortanix DSM a critical component of MongoDB’s client-side encryption strategy.

5.0 Configure Fortanix DSM

A Fortanix DSM service must be configured, and the URL must be accessible. To create a Fortanix DSM account and group, refer to the following sections:

5.1 Signing Up

To get started with the Fortanix Data Security Manager (DSM) cloud service, you must register an account at <Your_DSM_Service_URL>. For example, https://eu.smartkey.io.

For detailed steps on how to set up the Fortanix DSM, refer to the User's Guide: Sign Up for Fortanix Data Security Manager SaaS documentation.

5.2 Creating an Account

Access the <Your_DSM_Service_URL> on the web browser and enter your credentials to log in to the Fortanix DSM.

Figure 2: Logging In

5.3 Creating a Group

Perform the following steps to create a group in the Fortanix DSM:

  1. Click the Groups menu item in the DSM left navigation panel and click the button on the Groups page to add a new group.

    Figure 3: Add Groups

  2. On the Adding new group page, enter the following details:

    • Title: Enter a title for your group.

    • Description (optional): Enter a short description for the group.

  3. Click the SAVE button to create the new group.

The new group has been added to the Fortanix DSM successfully.

5.4 Creating an Application

Perform the following steps to create an application (app) in the Fortanix DSM:

  1. Click the Apps menu item in the DSM left navigation panel and click the button on the Apps page to add a new app.

    Figure 4: Add Application

  2. On the Adding new app page, enter the following details:

    • App name: Enter the name of your application.

    • ADD DESCRIPTION (optional): Enter a short description for the application.

    • Authentication method: Select the default API Key as the method of authentication from the drop down menu. For more information on app authentication methods, refer to User's Guide: Authentication documentation.

    • Assigning the new app to groups: Select the group created in Section 5.3: Creating a Group from the list.

  3. Click the SAVE button to add the new application. 

The new application has been added to the Fortanix DSM successfully.

5.5 Copying the App UUID

Perform the following steps to copy the app UUID from the Fortanix DSM:

  1. Click the Apps menu item in the DSM left navigation panel and click the app created in Section 5.4: Creating an Application to go to the detailed view of the app.

  2. From the top of the app’s page, copy the app UUID to be used in Section 5.6: Generating a Certificate as the value of Common Name (CN) to generate the certificate.

5.6 Generating a Certificate

Run the following OpenSSL command to generate a self-signed certificate. This certificate will be used later to authenticate the Fortanix DSM with MongoDB client and HTTP client:

openssl req -newkey rsa:2048 -nodes -keyout private.key -x509 -days 365 -out certificate.crt

When prompted, enter the app UUID as the CN, as copied in Section 5.5: Copying the App UUID.

A properly generated certificate should appear as follows:

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 11285796284824083476 (0x9c9f33ed245cdc14)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=US, ST=CA, L=Mountain View, O=Fortanix, OU=Test, CN=da7f2800-4122-4681-aebf-90beb779b73f/[email protected]
        Validity
            Not Before: Aug  8 23:31:20 2018 GMT
            Not After : Aug  8 23:31:20 2019 GMT
        Subject: C=US, ST=CA, L=Mountain View, O=Fortanix, OU=Test, CN=da7f2800-4122-4681-aebf-90beb779b73f/[email protected]
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:d2:ae:15:66:bf:78:d4:98:f4:4d:a5:57:bf:04:
                    08:76:83:1f:40:e8:8b:c4:da:8a:a0:71:22:43:84:
                    6d:c9:05:f2:81:91:83:04:75:bd:c9:83:86:92:bf:
                    ff:a0:e4:b4:e4:ee:56:09:10:2a:dc:e2:f4:0c:65:
                    43:96:a1:31:0d:15:92:49:87:ee:46:91:5d:f1:8c:
                    61:b3:ca:4a:9f:be:01:00:d5:30:5f:ee:56:35:75:
                    3c:e1:0d:a6:34:66:7f:3b:26:69:97:33:6d:2e:c7:
                    fd:c9:42:7d:14:f7:12:18:4a:5b:a6:90:52:7a:4b:
                    1b:45:b3:79:33:31:99:03:1d:a4:ed:51:dc:7b:43:
                    20:02:bb:08:22:27:27:8c:51:6a:5f:59:87:45:95:
                    d7:f3:ca:fa:30:3d:d5:a6:50:77:03:e3:de:eb:30:
                    17:45:48:fe:5b:76:d4:c1:03:3f:b8:99:73:ae:ad:
                    ae:e2:69:95:e2:14:1e:42:b1:ac:72:cd:0b:c6:01:
                    e3:20:8d:5a:6a:5d:19:79:17:f0:80:5f:75:fc:d5:
                    da:9c:af:07:d8:c7:96:02:a5:94:19:64:d7:9a:e4:
                    56:f1:cf:54:b9:a7:29:28:22:52:f2:c4:8a:97:04:
                    45:b1:9b:b5:4f:c0:18:53:ff:08:3f:3b:81:bd:f1:
                    d1:e9
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                87:65:C6:B6:B6:3A:0A:A6:30:BA:CB:D2:27:9E:C4:E6:2E:7F:2F:6D
            X509v3 Authority Key Identifier: 
                keyid:87:65:C6:B6:B6:3A:0A:A6:30:BA:CB:D2:27:9E:C4:E6:2E:7F:2F:6D

            X509v3 Basic Constraints: 
                CA:TRUE
    Signature Algorithm: sha256WithRSAEncryption
         71:da:8c:da:ab:9d:6d:8a:f1:9c:56:a9:7d:e2:e2:1b:fd:90:
         b7:5e:45:db:d4:69:47:ca:98:2f:b0:3b:2c:1f:49:3a:75:dd:
         1d:96:b3:bd:11:a6:d7:06:60:4f:18:11:e1:cf:db:5c:52:03:
         29:78:47:6e:36:c0:64:d8:4d:34:00:d9:94:55:48:a9:d4:b2:
         b2:ed:b8:13:fc:3d:c6:b4:61:a3:56:aa:9d:73:80:62:38:da:
         0c:94:b0:4a:e6:86:da:6a:f9:aa:f3:a4:3c:48:32:93:f7:d3:
         27:f9:2c:77:b4:91:9c:84:62:96:86:7d:d2:c8:20:79:d1:12:
         ef:f0:cc:15:31:ea:86:e9:b4:02:00:55:83:0f:6a:c6:5b:d2:
         19:67:9b:b2:44:f8:3b:36:f9:b0:02:b2:98:7d:1e:fa:95:58:
         92:92:57:68:f8:56:bb:43:db:01:08:bb:d6:ab:52:e6:c7:88:
         7a:1c:8d:f4:31:90:70:0a:dd:d2:96:7c:8b:93:8f:1f:4a:80:
         fe:3a:f8:df:82:a7:99:ac:2f:e8:02:e5:8b:fe:ec:3b:3b:0a:
         a3:c0:82:4d:f7:93:66:a1:76:6f:fa:c2:19:8e:d8:b6:b4:27:
         8c:57:22:a4:f7:e6:45:61:27:af:fc:5f:51:88:eb:32:

NOTE

Ensure that the subject in the certificate matches the app ID as CN to confirm proper validation and secure integration.

5.7 Updating the Authentication Method

Perform the following steps to update the authentication method of the app in the Fortanix DSM:

  1. Go to the detailed view of the app created in Section 5.4: Creating an Application and click the Change the authentication method button and select the Certificate option to change the authentication method to Certificate.

  2. Click the SAVE button.

  3. On the Add certificate dialog box, click the UPLOAD NEW CERTIFICATE button to upload the certificate file or paste the content of the certificate.crt file generated in Section 5.6: Generating a Certificate.

  4. Select both the check boxes to confirm your understanding about the action.

  5. Click the UPDATE button to save the changes.

5.8 Creating a Plugin

Perform the following steps to create a plugin in the Fortanix DSM that will be used to create or rotate the master keys for CSFLE usage:

  1. Click the Plugin menu item in the DSM left navigation panel and click the + NEW PLUGIN button to add a new plugin.

    Figure 5: Add Plugin

  2. On the NEW PLUGIN dialog box, select the CREATE/IMPORT A NEW PLUGIN option.

  3. On the Adding new plugin page, enter the following details:

    • Plugin name: Enter the name of your plugin.

    • ADD DESCRIPTION (optional): Enter a short description for the plugin.

    • Assigning the new plugin to groups: Select the group created in Section 5.3: Creating a Group from the drop down list.

  4. Click the NEXT button to proceed further.

  5. On the Add Plugin Code page, perform the following steps:

    1. Keep the default option selected as EDIT INLINE.

    2. Paste the plugin LUA code block from the Plugin library.

  6. Click the CREATE button to add the new plugin.

5.9 Copying the Plugin UUID

Perform the following steps to copy the UUID of the plugin from the Fortanix DSM:

  1. Click the Plugins menu item in the DSM left navigation panel and click the plugin created in Section 5.8: Creating a Plugin to go to the detailed view of the plugin.

  2. From the top of the plugin’s page, click the COPY UUID button to copy the UUID of the plugin to use it later in Section 6.3: Generating a Master Key to invoke the plugin and generate the master key.

    Figure 6: Copy Plugin UUID

6.0 Set Up MongoDB CSFLE with Fortanix DSM

This section outlines the necessary steps to configure MongoDB CSFLE with Fortanix DSM.

6.1 Setting Up SSL Certificates

This section illustrated how to configure Secure Sockets Layer (SSL) certificates using a TrustStore and KeyStore for secure communication with Fortanix DSM.

6.1.1 Configuring Keystore

Run the following command to create a certificate PKCS#12 file (certificate.p12) using the certificate and private key as generated in Section 5.6: Generating a Certificate:

openssl pkcs12 -export -out certificate.p12 -inkey <path_to_your_private_key> -in <path_to_your_certificate.crt>

Where,

The KeyStore contains the private key and signed certificate necessary for client-side authentication with the DSM application. The KeyStore is typically stored in the PKCS#12 format (.p12), which is a secure, portable format for both keys and certificates.

  • KeyStore Path: Specify the path to your PKCS#12 (.p12) file, which includes the private key and signed certificate. For example, /path/to/keystore.p12.

  • KeyStore Password: Provide the password that unlocks the KeyStore file to access the private key and certificate. For example, keyStorePassword.

System.setProperty("javax.net.ssl.keyStoreType", KEYSTORE_TYPE);
System.setProperty("javax.net.ssl.keyStore", KEYSTORE_PATH);
System.setProperty("javax.net.ssl.keyStorePassword", KEYSTORE_PASSWORD);

6.1.2 Configuring Truststore

Run the following command to convert the DSM root CA certificate into a Java KeyStore (JKS) file:

keytool -storetype JKS -importcert -file <dsm_root_ca.pem> -keystore dsm_root_ca.jks

Where,

The TrustStore is responsible for storing the DSM root certificate authority (CA) file to verify the DSM endpoint’s identity. This file is in the Java KeyStore (.jks) format.

  • TrustStore Path: Specify the path to your root CA certificate file in the .jks format. For example, /path/to/rootCA.jks.

  • TrustStore Password: Provide the password associated with the TrustStore to unlock the store and access the CA certificates. For example, trustStorePassword.

System.setProperty("javax.net.ssl.trustStoreType", TRUSTSTORE_TYPE);
System.setProperty("javax.net.ssl.trustStore", TRUSTSTORE_PATH);
System.setProperty("javax.net.ssl.trustStorePassword", TRUSTSTORE_PASSWORD);

6.2 Specifying the KMS Provider

To configure MongoDB to use Fortanix DSM as the KMS provider, the FortanixMongodbCSFLE.java file includes a pre-defined configuration that securely manages encryption keys.

 Map<String, Map<String, Object>> kmsProviders = new HashMap<String, Map<String, Object>>();
 Map<String, Object> providerDetails = new HashMap<>();
 providerDetails.put("endpoint", <KMS_ENDPOINT>);
 kmsProviders.put(<KMS_PROVIDER>, providerDetails);

Where,

  • <KMS_ENDPOINT> refers to the Fortanix DSM API endpoint URL that MongoDB will communicate with.

  • <KMS_PROVIDER> refers to the name of the KMS provider you are using. For example, kmip.

6.3 Generating a Master Key

To establish a secure connection with the Fortanix DSM and generate a master key, the FortanixMongodbCSFLE.java file includes a pre-defined configuration that uses the HttpClient to send a POST request to the Fortanix API endpoint, including the plugin UUID and authentication headers.

This request triggers the plugin to generate a master key as a SECRET security object in a 96-byte format. After receiving the response, you need to check for a successful status code (200). If the request is successful, the master key ID is extracted from the response. If the request fails, an error message is displayed, and the process is halted.

HttpClient client = HttpClient.newBuilder().build();
        // CERT BASED AUTHENTICATION
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(<FORTANIX_API_ENDPOINT> + "/sys/v1/plugins/" + <PLUGIN_UUID>))
                .header("Content-Type", "application/json")
                .header("Authorization", <AUTH_HEADER>)
                .POST(HttpRequest.BodyPublishers.ofString("{\"name\":\"96_byte_secret\",\"method\":\"create\"}"))
                .build();
        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
        String keyId = null;
        if (response.statusCode() == 200) {
            JSONObject responseObject = new JSONObject(response.body());
            keyId = responseObject.getString("kid");
            System.out.println("Successfully invoked plugin. CMK ID: " + keyId);
        } else {
            System.out.println("Request failed with status code: " + response.statusCode());
            System.exit(0);
        }

Where,

  • <FORTANIX_API_ENDPOINT> refers to the Fortanix DSM API endpoint URL. For example, https://amer.smartkey.io.

  • <PLUGIN_UUID> refers to the UUID of the Fortanix DSM plugin as copied in the Section 5.9: Copying the Plugin UUID.

  • <AUTH_HEADER> refers to the credentials used for authentication.

After the variables are updated, a master key will be generated and it returns an ID, which will be used for generating a DEK.

6.4 Generating a Data Encryption Key

To generate a Data Encryption Key (DEK) for encrypting sensitive data in MongoDB, the FortanixMongodbCSFLE.java file includes a pre-defined configuration that utilizes MongoDB’s clientEncryption object. The DEK is encrypted using the master key stored in Fortanix DSM.

ClientEncryptionSettings clientEncryptionSettings = ClientEncryptionSettings.builder()
                .keyVaultMongoClientSettings(MongoClientSettings.builder()
                        .applyConnectionString(new ConnectionString(MONGO_CONNECTION_STRING))
                        .build())
                .keyVaultNamespace(KEY_VAULT_NAMESPACE)
                .kmsProviders(kmsProviders)
                .build();
        ClientEncryption clientEncryption = ClientEncryptions.create(clientEncryptionSettings);
        Document masterKeyProperties = new Document().append("keyId", <MASTER_KEY_ID>);        
        BsonBinary dataKeyId = clientEncryption.createDataKey(KMS_PROVIDER, new DataKeyOptions().masterKey(masterKeyProperties.toBsonDocument()));

Where,

  • <MONGO_CONNECTION_STRING> refers to the connection string for your MongoDB instance. For example, mongodb://localhost:27017.

  • <KEY_VAULT_NAMESPACE> refers to the namespace where your key vault is configured. For example, admin.keyvault.

  • <MASTER_KEY_ID> refers to the master key ID stored in Fortanix DSM as returned in Section 6.3: Generating a Master Key.

  • <KMS_PROVIDER> refers to the name of the KMS provider you are using. For example, kmip.

You can select the encryption algorithms such as:

  • For fields requiring deterministic encryption: AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic

  • For fields requiring random encryption: AEAD_AES_256_CBC_HMAC_SHA_512-Random

NOTE

Ensure to save the DEK ID as a base64-encoded string for schema validation.

6.5 Setting Up MongoDB Clients

To set up MongoDB clients with encrypted fields, the FortanixMongodbCSFLE.java file includes a pre-defined configuration that applies strong encryption algorithms to selected fields.

  • Regular Client: MongoDB connects without encryption or decryption, allowing access to data in its stored form.

    // client settings builder without KMIP
    MongoClientSettings clientSettingsRegular = MongoClientSettings.builder()
            .applyConnectionString(new ConnectionString(<MONGO_CONNECTION_STRING>))
            .build();
    MongoClient mongoClientRegular = MongoClients.create(clientSettingsRegular);
  • Secure Client: MongoDB connects with automatic encryption and decryption using the DEK so that the data is stored in an encrypted form.

            // client settings builder with KMIP
            MongoClientSettings clientSettings = MongoClientSettings.builder()
                    .applyConnectionString(new ConnectionString(<MONGO_CONNECTION_STRING>))
                    .autoEncryptionSettings(AutoEncryptionSettings.builder()
                            .keyVaultNamespace(<KEY_VAULT_NAMESPACE>)
                            .kmsProviders(kmsProviders)
                            .schemaMap(schemaMap)
                            .build())
                    .build();
    
            MongoClient mongoClientSecure = MongoClients.create(clientSettings);

Where,

  • <MONGO_CONNECTION_STRING> refers to the MongoDB connection string, including credentials and the database to connect to.

  • <KEY_VAULT_NAMESPACE> refers to the namespace, the MongoDB database and collection, where your encryption keys are stored. For example, encryption.keys.

After the variables are updated, the Secure Client will automatically handle encryption and decryption based on the provided schema.

6.6 Selecting Encryption Methods and Fields to Encrypt

To specify encryption methods and fields for encryption, the FortanixMongodbCSFLE.java file includes a pre-defined configuration that ensures only sensitive data is encrypted using strong encryption algorithms.

        // start-schema
        Document jsonSchema = new Document().append("bsonType", "object").append("encryptMetadata",
                        new Document().append("keyId", new ArrayList<>((Arrays.asList(new Document().append("$binary", new Document()
                                .append("base64", base64DataKeyId)
                                .append("subType", "04")))))))
                .append("properties", new Document()
                        .append("<FIELDS_TO_ENCRYPT>", new Document().append("encrypt", new Document()
                                .append("bsonType", "int")
                                .append("algorithm", "<ENCRYPTION_ALGORITHM>")))
                        .append("<FIELDS_TO_ENCRYPT>", new Document().append("encrypt", new Document()
                                .append("bsonType", "string")
                                .append("algorithm", "<ENCRYPTION_ALGORITHM>"))));
        HashMap<String, BsonDocument> schemaMap = new HashMap<String, BsonDocument>();

Where ,

  • ENCRYPTION_ALGORITHM refers to the encryption method selected, such as AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic or AEAD_AES_256_CBC_HMAC_SHA_512-Random.

  • FIELDS_TO_ENCRYPT refers to the fields you choose to encrypt, such as employeeID.

6.7 Inserting the Encrypted Document

To insert an encrypted document, the FortanixMongodbCSFLE.java file includes a pre-defined configuration that fetches the master key from DSM to decrypt the DEK stored in the MongoDB Key Vault collection. The decrypted DEK then encrypts the specified fields before the document is inserted into the database.

For example,

{
  "name": "Alice", 
  "employeeID": 12345, 
  "city": "Bengaluru"
}

6.8 Querying the Encrypted Document

To retrieve encrypted documents, the FortanixMongodbCSFLE.java file includes a pre-defined configurations where the Regular Client fetches data in its encrypted form, while the Secure Client automatically decrypts the specified fields for seamless execution.

  • The Regular Client queries the encrypted document in MongoDB. The data will remain encrypted when retrieved.

    Document docRegular = mongoClientRegular.getDatabase(DB_NAME).getCollection(COLLECTION_NAME).find(eq("name", EMPLOYEE_NAME)).first();
  • The Secure Client queries the encrypted document in MongoDB. The data will be decrypted automatically by the secure client.

    Document docSecure = mongoClientSecure.getDatabase(DB_NAME).getCollection(COLLECTION_NAME).find(eq("name", EMPLOYEE_NAME)).first();

Where,

  • <DB_NAME> refers to the name of your database.

  • <COLLECTION_NAME>  refers to the collection storing the encrypted data.

  • <EMPLOYEE_NAME> refers to the query criteria for searching the document.

6.9 Closing the MongoDB Client

To properly close the MongoDB connection after completing operations, the FortanixMongodbCSFLE.java file includes a predefined configuration to close the Secure Client using the following command:

// Close the clients
mongoClientRegular.close();
mongoClientSecure.close();

6.10 Verifying the DSM Audit Logs

After successfully executing the FortanixMongodbCSFLE.java file, a master key will be automatically generated and securely stored within your Fortanix DSM group as created in Section 5.3: Creating a Group.

This key serves as the root of trust for encrypting and decrypting data within your MongoDB CSFLE setup. You can navigate to the Fortanix DSM UI → Audit Log to verify the creation and usage of the master key.

Figure 7: Verify Audit Log

7.0 Key Rotation and Rewrapping

Figure 8: Rotating the Master Key and Rewrapping the DEK Workflow

This diagram illustrates the process of rotating the master key and rewrapping the DEK to secure the key lifecycle management in Fortanix DSM.

7.1 Rotating the Master Key

To enhance security and follow key management best practices, the RotateCMK.java file (downloaded from the GitHub repository) includes a predefined configuration to rotate the master key stored in Fortanix DSM.

The rotation process involves invoking the Fortanix DSM plugin with the existing master key ID to generate a new master key. This is done by sending an HTTP request using the HttpClient, which communicates with the Fortanix DSM endpoint. After successful execution, a new master key UUID is returned, replacing the old key while maintaining secure access to encrypted data.

    private static String sendRotateRequest(String <oldCMKId>) throws Exception {
        HttpClient client = HttpClient.newBuilder().build();
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(<FORTANIX_API_ENDPOINT> + "/sys/v1/plugins/" + <PLUGIN_UUID>))
                .header("Content-Type", "application/json")
                .header("Authorization", <AUTH_HEADER>)
                .POST(HttpRequest.BodyPublishers.ofString("{\"kid\":\"" + oldCMKId + "\",\"method\":\"rotate\"}"))
                .build();
        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
        if (response.statusCode() == 200) {
            JSONObject responseObject = new JSONObject(response.body());
            System.out.println("CMK successfully rotated. New Master Key UUID: " + responseObject.getString("kid"));
            return responseObject.getString("kid");
        } else {
            System.out.println("Request failed with status code: " + response.statusCode() + "\nError: " + response.body());
            return null;
        }

    }

Where,

  • <FORTANIX_API_ENDPOINT> refers to the Fortanix DSM API endpoint URL. For example, https://eu.smartkey.io.

  • <PLUGIN_UUID> refers to the UUID of the Fortanix DSM plugin as copied in the Section 5.9: Copying the Plugin UUID.

  • <AUTH_HEADER> refers to the authorization token used for authentication.

  • <oldCMKId> refers to the existing master key ID as returned in Section 6.3: Generating a Master Key that needs to be rotated.

7.2 Rewrapping the Data Encryption Key

To enhance security and follow key management best practices, the RotateCMK.java file includes a predefined configuration to rewrap the DEKs after rotating the master key.

The rewrapping process involves invoking MongoDB’s rewrapManyDataKey function with the new master key ID to update the encryption of existing DEKs. This is done by establishing a connection with MongoDB and executing the rewrap operation using the specified KMS provider. After successful execution, the DEKs are securely rewrapped with the new master key, ensuring continued protection of encrypted data.

  try (MongoClient mongoClient = MongoClients.create(<MONGO_CONNECTION_STRING>);
            ClientEncryption clientEncryption = ClientEncryptions.create(clientEncryptionSettings)) {
            Bson filter = new Document();
            Document masterKeyProperties = new Document().append("keyId", <newCMKId>);
            RewrapManyDataKeyOptions rewrapManyDataKeyOptions = new RewrapManyDataKeyOptions()
                    .masterKey(masterKeyProperties.toBsonDocument())
                    .provider(<KMS_PROVIDER>);
            RewrapManyDataKeyResult result = clientEncryption.rewrapManyDataKey(filter, rewrapManyDataKeyOptions);
            System.out.println("Rewrapped Data Keys: " + result.getBulkWriteResult().getModifiedCount());
 }

Where,

  • <MONGO_CONNECTION_STRING> refers to the connection string for the MongoDB instance.

  • <newCMKId> refers to the newly rotated master key ID used for rewrapping the DEK as returned in Section 7.1: Rotating the Master Key.

  • <KMS_PROVIDER> refers to the name of the KMS provider you are using. For example, kmip.