public class EncryptionUtil {
private static final String ALGO = 'AES-GCM';
private static final Integer IV_LENGTH = 12; // Recommended length for GCM
private static final Integer KEY_LENGTH = 32; // 256 bits
public class EncryptionResult {
public String encryptedTextWithTag;
public String keyiv;
public EncryptionResult(String encryptedTextWithTag, String keyiv) {
this.encryptedTextWithTag = encryptedTextWithTag;
this.keyiv = keyiv;
}
}
/**
* Encrypts plaintext using AES-256-GCM algorithm
* @param plaintext The text to encrypt
* @return EncryptionResult containing encrypted text and key+iv
*/
public static EncryptionResult encryptAES256(String plaintext) {
try {
// Generate random key and IV
Blob key = Crypto.generateAesKey(256);
Blob iv = Crypto.generateRandomIV();
// Encrypt the plaintext
Blob plaintextBlob = Blob.valueOf(plaintext);
Blob encryptedBlob = Crypto.encryptWithManagedIV('AES256', key, plaintextBlob);
// Convert to base64 strings
String encryptedTextWithTag = EncodingUtil.base64Encode(encryptedBlob);
String keyString = EncodingUtil.base64Encode(key);
String ivString = EncodingUtil.base64Encode(iv);
String keyiv = keyString + '^' + ivString;
return new EncryptionResult(encryptedTextWithTag, keyiv);
} catch (Exception e) {
throw new AuraHandledException('Error occurred while encrypting AES256: ' + e.getMessage());
}
}
/**
* Decrypts AES-256-GCM encrypted text
* @param encryptedTextWithTag The encrypted text (base64 encoded)
* @param keyiv The key and IV in format "key^iv" (base64 encoded)
* @return Decrypted plaintext
*/
public static String decryptAES256(String encryptedTextWithTag, String keyiv) {
try {
// Parse key and IV
List<String> parts = keyiv.split('\\^');
if (parts.size() != 2) {
throw new IllegalArgumentException('Invalid keyiv format. Expected format: key^iv');
}
Blob key = EncodingUtil.base64Decode(parts[0]);
Blob iv = EncodingUtil.base64Decode(parts[1]);
Blob cipherText = EncodingUtil.base64Decode(encryptedTextWithTag);
// Decrypt
Blob decryptedBlob = Crypto.decryptWithManagedIV('AES256', key, cipherText);
return decryptedBlob.toString();
} catch (Exception e) {
throw new AuraHandledException('Error occurred while decrypting AES256: ' + e.getMessage());
}
}
/**
* Encrypts plaintext using RSA with public key
* @param plaintext The text to encrypt
* @param publicKeyName The name of the public key stored in Salesforce
* @return Encrypted text (base64 encoded)
*/
public static String rsaEncryptWithPublicKey(String plaintext, String publicKeyName) {
try {
// Get the public key certificate from Salesforce
List<Certificate> certificates = [
SELECT Id, PrivateKeyChecksum, PublicKeyChecksum
FROM Certificate
WHERE DeveloperName = :publicKeyName
LIMIT 1
];
if (certificates.isEmpty()) {
throw new IllegalArgumentException('Certificate not found: ' + publicKeyName);
}
Certificate cert = certificates[0];
Blob plaintextBlob = Blob.valueOf(plaintext);
// Encrypt with public key
Blob encryptedBlob = Crypto.encryptWithPublicKey('RSA2048', plaintextBlob, cert);
return EncodingUtil.base64Encode(encryptedBlob);
} catch (Exception e) {
throw new AuraHandledException('Error occurred while encrypting RSA Key: ' + e.getMessage());
}
}
}
EncryptionUtil.EncryptionResult result = EncryptionUtil.encryptAES256('sensitive data');
System.debug('Encrypted: ' + result.encryptedTextWithTag);
System.debug('Key+IV: ' + result.keyiv);