Develop A Class For Encryption Utilities.

Story from the User’s Perspective

We aim to encrypt our data using an AES encryption key without having to spend money on the Salesforce Data Masking package. As an illustration, we are presenting at Forcelandia on March 23th and 24th, 2024, and intend to obscure certain phone numbers in our API project development organization.

Resolution


This one was a bit tricky, but after spending about an hour experimenting with it, I managed to devise a solution.

Step One – Establish a Custom Metadata Type


A Custom Metadata Type resembles an sObject in structure and enables us to define a default value for an element within our Salesforce organization. Our Custom Metadata Type will be named AES_Key.

We’ll incorporate a custom field named key__c to manage, as you might have guessed, our key.

Step Two – Create an AES Key

Next, we are going to generate our key using Developer Console.

We will input the following command:

System.debug(EncodingUtil.base64Encode(Crypto.generateAesKey(128))); This command will provide us with a key in our debug log. Returning to our Custom Metadata Type, we will insert a new record.

Step Three – Develop an Apex Class

public with sharing class EncryptionUtil {
    
    public static final String CIPHER = 'AES128';

    public static Blob key {
        get {
            return EncodingUtil.base64Decode((AES_Key__mdt.getInstance('Encryption_Key').key__c));
        }
        set;
    }
public static String encryptString(String stringToEncrypt) {
        Blob data = Blob.valueOf(stringToEncrypt);

        Blob encryptedBlob = Crypto.encryptWithManagedIV(CIPHER, EncryptionUtil.key, data);

        String encryptedString = EncodingUtil.base64Encode(encryptedBlob);

        return encryptedString;
    }
public static String decryptString(String stringToDecrypt) {
        Blob data = EncodingUtil.base64Decode(stringToDecrypt);

        Blob decryptedBlob = Crypto.decryptWithManagedIV(CIPHER, EncryptionUtil.key, data);

        String decryptedString = decryptedBlob.toString();
        
        return decryptedString;
    }
}

The most challenging aspect was determining the appropriate decoding methods to utilize. Let’s analyze it step by step.

To begin, let’s examine our getter:

public static Blob key {
        get {
            return EncodingUtil.base64Decode((AES_Key__mdt.getInstance('Encryption_Key').key__c));
        }
        set;
    }

Our encryption key is presently saved as a string within our Custom Metadata setting, necessitating its conversion into a Blob.

Within our encryptString method, we receive a string parameter, convert it into a Blob for utilization in the Crypto.encryptWithManagedIV(String, Blob, Blob) method, produce a Blob output, and subsequently encode that Blob into a String.

public static String encryptString(String stringToEncrypt) {
        Blob data = Blob.valueOf(stringToEncrypt);

        Blob encryptedBlob = Crypto.encryptWithManagedIV(CIPHER, EncryptionUtil.key, data);

        String encryptedString = EncodingUtil.base64Encode(encryptedBlob);

        return encryptedString;
    }


In our decryptString method, we essentially reverse this process.

We receive a string parameter, decode it into a blob, and then convert it back to a string using the .toString() method of the Blob class.

public static String decryptString(String stringToDecrypt) {
        Blob data = EncodingUtil.base64Decode(stringToDecrypt);

        Blob decryptedBlob = Crypto.decryptWithManagedIV(CIPHER, EncryptionUtil.key, data);

        String decryptedString = decryptedBlob.toString();
        
        return decryptedString;
    }

The most challenging aspect of this process is understanding the appropriate Blob, Crypto, and EncodingUtil methods to employ and their sequence.

Essentially, we convert a string into binary, encrypt it, and then encode it back into a string. Conversely, during decryption, we perform the reverse steps.

Step Four – Validate our methods

We can test our methods by using Anonymous Apex again:

This will yield the following results in the debug log:


I look forward to meeting you at Forcelandia this summer!

Thank you for reading. Please feel free to share any comments or questions you may have!