MongoDB Field Encryption and Decryption using C# MongoDB driver

MongoDB Field Encryption and Decryption

Today in this article, we shall see how to achieve MongoDB Field Level Encryption and Decryption C# .NET.

Today in this article, we will cover below aspects,

This technique could be very useful for encrypting the PII or PHI details in MongoDB.

MongoDB 4.2 onwards now there is support for client-side field-level encryption allowing administrators and developers to encrypt specific data fields.

This is an addition to in addition to other existing MongoDB encryption features.

There are a few guidelines listed below which must be considered before you could look into this feature support.

  • Field-level encryption is supported for feature needs MongoDB4.2 and onwards support.

  • With client-side field-level encryption, developers can encrypt fields client-side.

  • Encrypt fields are supported without any server-side configuration or directives.

  • Client-side field-level encryption in the .NET/C# driver is currently only supported on x64-compatible CPUs.

Today in this article, we will see an example of how to implement automatic encryption and decryption of fields in MongoDB.

Below I have sample fields in the MongoDB which we will be encrypting and decrypting in the MongoDB database,

Below we are using the Ssn field originally defined as a string datatype in the Mongo schema

MongoDB Field Level Encryption and Decryption

MongoDB Field Level Encryption – Getting started

Please create any .NET/.NET Core C# application.

Please add the MongoDB driver NuGet package using the Nuget Package manager.

PM> Install-Package MongoDB.Driver -Version 2.13.2

I shall keep the MongoDB driver interface used here simple enough to concentrate on how to add new fields to existing documents.

Please visit for better approaches like using DI or IOC here,

Step I – Define the ClientEncryptionOptions

Let’s Initialize a new instance of MongoDB.Driver.Encryption.ClientEncryptionOptions
class. This required keyVaultClient, keyVaultNamespace, and kmsProviders as input parameters.

             //  ClientEncryption instance
             var clientEncryptionSettings = new ClientEncryptionOptions(
                 keyVaultClient,
                 keyVaultNamespace,
                 kmsProviders);

Where keyVaultClient is defined as below,

var keyVaultClient = new MongoClient("mongodb://<host-name>");

Step II – Define keyVaultNamespace

 var keyVaultNamespace = CollectionNamespace.FromFullName("admin.datakeys");

Step III – Define kmsProviders

             var localMasterKey = Convert.FromBase64String(LocalMasterKey);
             var kmsProviders = new Dictionary>();
             var localKey = new Dictionary
             {
                 { "key", localMasterKey }
             };
             kmsProviders.Add("local", localKey);

Where LocalMasterKey is a base64 string,

Example

private const string LocalMasterKey = "Mng0NCt4ZHVUYUJCa1*********";

Please add below using namespace in the application ,

using MongoDB.Driver.Encryption;

Let’s Update the SSN field with encryption

 
using (var clientEncryption = new ClientEncryption(clientEncryptionSettings))
            {
                var dataKeyId = clientEncryption.CreateDataKey(
                    "local",
                    new DataKeyOptions(),
                    CancellationToken.None);

                Console.WriteLine($"Original string {originalSsn}.");

                // Explicitly encrypt a field
                var encryptOptions = new 
 EncryptOptions(EncryptionAlgorithm.AEAD_AES_256_CBC_HMAC_SHA_512_Deterministic.ToString(),
                    keyId: dataKeyId);


                var SocialSecurityNumber = clientEncryption.Encrypt(
                    originalSsn,
                    encryptOptions,
                    CancellationToken.None);

                Console.WriteLine($"Encrypted value {SocialSecurityNumber}.");

                var filterDefinition = Builders<Employee>.Filter.Eq(p => p.EmpID, "100");
                var updateDefinition = Builders<Employee>.Update.Set(p => p.Ssn, SocialSecurityNumber);

                collection.UpdateOne(filterDefinition, updateDefinition);
              }

  • we have encrypted the MongoDB field called Ssn

  • The above also enables explicit Encryption and Auto Decryption by setting the property called bypassAutoEncryption=true

MongoDB Field Encryption and Decryption

In the above logic, we are passing the value of SSN as original Ssn= “123456789” which is encrypted to a binary string.

AutoDecryption of an encrypted field

Let’s now read/retrieve any values from MongoDB. While retrieving the value will be retrieved as decrypted without the need for us to write custom logic for decryption.

var decryptedValue = collection.Find(FilterDefinition.Empty).First();
MongoDB AutoDecryption

References:

Do you have any comments or ideas or any better suggestions to share?

Please sound off your comments below.

Happy Coding !!



Please bookmark this page and share it with your friends. Please Subscribe to the blog to receive notifications on freshly published(2024) best practices and guidelines for software design and development.



3 thoughts on “MongoDB Field Level Encryption and Decryption C# .NET

  1. Hi,

    Great article, but we can’t seem to get this working. What datatype is the originalSsn in your model? Do you have a Git-repo you could link this solution to?

    1. Hey Marcus- Glad you liked the article. I have used string datatype for originalSsn field in the DTO model. I will put the sample example in GitHub repo soon.

Leave a Reply

Your email address will not be published. Required fields are marked *