I have a requirement to store sensitive customer information in a protected custom setting in our installed package.

From my understanding through this answer the information should be encrypted before storing it on the custom setting record.

How can the key be stored so that the code can encrypt/decrypt the info but the package developer cannot see the key that is used for encrypting/decrypting?

1 Answer 1



Short Answer. No.

Long Answer

As a managed packaged, you will need access to the encryption key to encrypt/decrypt data whatever the use case be. Once a subscriber access is given, the logged in user (the developer) will also have access to the protected settings and the debug logs, where the key is visible.

There are some best practices that you can follow to store sensitive data:

  1. Auto generate encryption keys on PostInstall or when required. That way, the developer and the client won't know what the encryption keys are. (Except when subscriber access is given)
  2. Generate an org-wide, profile-based, and user-based encryption keys using the hierarchy feature of Custom Settings. That way, when a key is compromised, the rest of the data encrypted with different keys are safe
  3. Be as restrictive as possible when encrypting the data. If only the user who encrypted the value needs access to it, then use the user's key to encrypt the value
  4. After all this work to secure the keys, make sure to use the keys to encrypt sensitive data

Below are some utility function:

Encrypt Function

public static String encrypt(String plainText, Id setupOwnerId) {
    String encryptedValue =
            System.EncodingUtil.base64Encode(System.Crypto.encryptWithManagedIV('AES256', getCryptoKey(setupOwnerId), System.Blob.valueOf(plainText)));
    String hmacValue =
            System.EncodingUtil.base64Encode(System.Crypto.generateMac('HmacSHA256', System.Blob.valueOf(encryptedValue), getCryptoHmacKey(setupOwnerId)));
    return hmacValue + encryptedValue;

Decrypt Function

public static String decrypt(String encryptedText, Id setupOwnerId) {
    String hmacValue = encryptedText.substring(0, 44);
    String encryptedValue = encryptedText.substring(44);
    if(!System.Crypto.verifyHMac('HmacSHA256', System.Blob.valueOf(encryptedValue), getCryptoHmacKey(setupOwnerId),
                                 System.EncodingUtil.base64Decode(hmacValue))) {
        throw new HandledException(ENCRYPTION_KEY_NOT_VALID + setupOwnerId);
    return System.Crypto.decryptWithManagedIV('AES256', getCryptoKey(setupOwnerId), System.EncodingUtil.base64Decode(encryptedValue)).toString();

Generate Hmac and Crypto key


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .