“Good crypto is boring: unique IVs, rotated keys, verified MACs—repeat forever.”
The Apex Crypto class gives you symmetric encryption (AES), hashing, HMACs, and signatures—right inside Salesforce. Use it when you need to protect sensitive fields before storage or transport, or when you must encrypt payloads going to external systems.
• Use Apex Crypto for application-level encryption: specific fields, transient payloads, and custom protocols.
• Use Shield/Platform Encryption for at-rest encryption managed by Salesforce across standard/custom fields and files—no custom code required.
Many orgs use both: Shield for broad at-rest coverage, Apex Crypto for targeted field-level or integration use cases.
I thought I'd add some nice flowers to see if anyone is reading - cheer your day up a bit :)
Store keys in a secure keystore (named credentials, external secrets manager, or KMS). Never hardcode keys or IVs in Apex. Rotate keys on a schedule and tag ciphertext with the key version.
Modern Apex includes helper methods that handle the Initialization Vector (IV) for you. Below is a minimal pattern using AES-256:
// Generate a 256-bit key once (outside code); fetch it securely at runtime.
Blob key = Crypto.generateAesKey(256); // demo only; do not generate per request
String plaintext = 'Sensitive Value 123';
Blob data = Blob.valueOf(plaintext);
// Encrypt with managed IV (IV is stored alongside ciphertext)
Blob cipher = Crypto.encryptWithManagedIV('AES256', key, data);
// Decrypt with managed IV
Blob clear = Crypto.decryptWithManagedIV('AES256', key, cipher);
System.debug(clear.toString());
If an external system requires a specific mode/format, you can supply the IV yourself. Always use a unique, random IV per encryption operation:
Blob key = Crypto.generateAesKey(256);
Blob iv = Crypto.generateInitializationVector('AES256');
Blob cipher = Crypto.encrypt('AES256', 'CBC', key, iv, Blob.valueOf('Hello'));
Blob clear = Crypto.decrypt('AES256', 'CBC', key, iv, cipher);
Tip: Send IV and ciphertext together (e.g., Base64(iv) + ':' + Base64(cipher)). IVs are not secrets, but they must be unpredictable and non-reused.
Encryption hides data; it doesn’t prove it wasn’t tampered with. Add an HMAC:
Blob macKey = Crypto.generateAesKey(256);
Blob hmac = Crypto.generateMac('HmacSHA256', cipher, macKey);
// Verify on read:
Boolean ok = Crypto.verifyMac('HmacSHA256', cipher, macKey, hmac);
if (!ok) { throw new SecurityException('Ciphertext tampered.'); }
• Fetch keys from Named Credentials (JWT/External Secrets) or a KMS—not from Custom Settings/Metadata.
• Version your keys: include a version header; rotate regularly.
• Least privilege: restrict which users/profiles execute crypto code paths.
• Backups: losing keys = losing data. Protect, escrow, and audit access.
• Logging: log key version and operation, never raw keys or plaintext.
• Reusing IVs with the same key (weakens confidentiality).
• Storing keys in code, unmanaged packages, or unsecured custom settings.
• Encrypting already-encrypted fields without a reason (double-encrypt headaches).
• Skipping an integrity check (HMAC) when using CBC.
• Forgetting field lengths: ciphertext + IV + tag are larger than plaintext.
“Good crypto is boring: unique IVs, rotated keys, verified MACs—repeat forever.”
“Encrypt with intention, store keys like treasure, and your auditors will become your biggest fans.”
“Your pipeline should reject code that mishandles keys. Mercy in dev is chaos in prod.”
Next step for your business: we can blueprint key storage, build reusable crypto utilities, and add automated checks so encryption becomes a habit, not a firefight.