Implementing Encryption in Microsoft Dynamics NAV


There are many ways to do things. Take encryption, for example. Before a few days, I read an article titled Encrypting Data in NAV using SQL with ADO, by Rashed Amini. This article described a way of encrypting data in NAV using the encryption features provided by SQL Server.

In this article, I’ll describe a way of doing this using a .NET generated COM dll.

Scenario:

I have a fictional customer who wants to implement credit card charging via NAV. For implementing this functionality, a field called “Credit Card No.” is to be added to the Customer table.

The value of the “Credit Card No.” field will be entered using the “Customer Card” window. Before saving the value of that field to the table, it must be encrypted.

When the “Customer Card” window is opened to view an existing customer, the credit card number field must be decrypted and display a masked value of the format “xxxx-xxxx-xxxx-1234″.

Tools Used:

I am using Microsoft Dynamics NAV 2009 SP1 for performing the customization, and Visual Studio 2008 for writing the .NET COM component.

Implementing the COM dll:

I searched CodeProject.com and found an article about implementing Triple DES algorithm using .NET. I picked the C# code mentioned in the article, made a few changes to it, and added it to a class library project. I made the output of the class library “COM-visible”. You can do this by right-clicking the project, and going to “Properties” > “Application” tab > clicking “Assembly Information” > check “Make assembly COM-visible”. Also check the “Register for COM interop” checkbox in the Build tab. This will register the COM assembly in the registry.

As I mentioned before a few sentences, I have made a few changes to the code. One of the change that I made was creating an interface containing 2 methods “EncryptString” & “DecryptString”. I have implemented this interface in a class which contains the encryption/decryption method definition. For more details, you can take a look at the source code, its self explanatory.

Implementing the EncryptString/DecryptString Methods in NAV:

I have chosen Codeunit 1 to implement the EncryptString & DecryptString methods. These methods will accept a string parameter, and return the encrypted & decrypted string respectively.

The code for EncryptString & DecryptString methods is given below:

PROCEDURE EncryptString@1100495001(StringData@1100495001 : Text[1024]) EncryptedString : Text[1024];
VAR
TripleDES@1100495000 : Automation “{09B97DBF-A155-40B1-95DD-633D8672A9D3} 1.0:{8B3A39BA-5039-4248-A1FF-5455555400F8}:’TripleDES’.TripleDES”;
BEGIN
IF NOT ISCLEAR(TripleDES) THEN
CLEAR(TripleDES);

CREATE(TripleDES);
EncryptedString := TripleDES.Encrypt(StringData);
CLEAR(TripleDES);
END;

PROCEDURE DecryptString@1100495002(StringData@1100495000 : Text[1024]) DecryptedStringString : Text[1024];
VAR
TripleDES@1100495001 : Automation “{09B97DBF-A155-40B1-95DD-633D8672A9D3} 1.0:{8B3A39BA-5039-4248-A1FF-5455555400F8}:’TripleDES’.TripleDES”;
BEGIN
IF NOT ISCLEAR(TripleDES) THEN
CLEAR(TripleDES);

CREATE(TripleDES);
DecryptedStringString := TripleDES.Decrypt(StringData);
CLEAR(TripleDES);
END;

The actual customization:

So, the base for the customization has been set up. Now, its time for the actual customization.

I have added a field [”Credit Card No.” Code 50] to the Customer table.

I have also added a global variable [”CreditCardNo” Code 50] to the “Customer Card” page. After adding the global variable, I have added a field in the “Invoicing” tab, with the source expression set to the global variable just declared.

The global variable is the placeholder for the decrypted credit card values, as the actual value in the field will be encrypted.

I have written few lines of code in the OnValidate event of the “Credit Card No.” field in the Customer table. Here it is:

OnValidate=VAR
EncDecUtil@1100495000 : Codeunit 1;
BEGIN
IF xRec.”Credit Card No.” <> Rec.”Credit Card No.” THEN
“Credit Card No.” := EncDecUtil.EncryptString(”Credit Card No.”);
END;

Here, EncDecUtil is the instance of Codeunit 1, and whenever the value in the “Credit Card No.” field changes, I am updating the field with the encrypted value. This code handles the encryption logic; it will be called from the Customer Card.

I have also added a function to this table. This function contains the decryption and masking logic. It returns the masked string to the caller:

PROCEDURE GetMaskedCreditCardNo
IF “Credit Card No.” <> ” THEN
BEGIN
CreditCardNo := EncDecUtil.DecryptString(”Credit Card No.”);
StringLength := STRLEN(CreditCardNo);

IF StringLength > 4 THEN
BEGIN
CreditCardNo := ‘XXXX-XXXX-XXXX-’ + COPYSTR(CreditCardNo, StringLength - 3, 4);
END;
END
ELSE
BEGIN
CreditCardNo := ”;
END;

Here, CreditCardNo is the return variable.

I have added this code in the OnValidate event of the CreditCardNo field in the Customer Card:

VALIDATE(”Credit Card No.”, CreditCardNo);

This code will call the OnValidate event of the “Credit Card No.” field in the table, and that event, in turn, will update the table field with the encrypted value.

Now, after I get each record, I want to decrypt the “Credit Card No.” field, mask it, and show it on the card. I have written this code in the OnAfterGetRecord event of the Customer Card:

CreditCardNo := Rec.GetMaskedCreditCardNo();

Every time a record is fetched, the GetMaskedCreditCardNo method will return the decrypted and masked credit card number.

So, that’s it!!

Downloads:

You must be logged in to post a comment.