MongoDB Field Encryption and Decryption using C# MongoDB driver
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 – 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
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();
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.
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?
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.
Hi – This article helped me in great way! Keep up the good work