This article explains useful information that will help you understand and successfully use the Apex Crypto class.
As per the Crypto Class documentation in the Apex Developer's Guide, the Apex Crypto class provides a number of cryptographic functions for creating digests, message authentication codes, and signatures, as well as functions for encrypting and decrypting information. These functions allow you to protect the confidentiality of data as well as allow external systems to verify the integrity of messages and authenticity of the sender.
The cryptographic capabilities of the Crypto class is normally used in the following scenarios:
Consists of functions to encrypt and decrypt information using AES128, AES192 and AES256 algorithms. Currently, only symmetric private key encryption using the AES algorithm is supported. Whilst encryption provides for data protection, it does not authenticate the sender (non-repudiation) and nor does it guarantee message integrity.
In this scenario, the input message of any length is converted using a one-way cryptographic hash function into a compact unique "digest" of fixed length. As the digest is unique, it can then be used by the receiver to ensure integrity of the message by comparing the transmitted digest with a digest calculated from the received message using the same algorithm. Its compact nature also allows for performance and efficient transmission.
The Crypto.generateDigest() function generates a one-way hash digest for this purpose and supports algorithms such as MD5, SHA1, SHA256 and SHA512. As hash digests are one way, compact representations of the original data, the resulting digest cannot be "decrypted" back to its original form.
Hash-based MAC functions generate a compact one-way digest using a cryptographic hash function and then uses a private key to encrypt the resulting digest. The combination of the an encrypted hash digest ensures non-repudiation of the message and its sender.
Compared to a hash digests, HMAC functions use a private key that the sender uses to encrypt the MAC and receiver to decrypt the MAC. The unencrypted digest can then verify the message integrity. As the receiver has to decrypt the MAC using the shared private key, you can verify the authenticity of the message sender.
The Crypto.generateMac() method supports the HMACMD5, HMACSHA1, HMACSHA256 and HMAC512 algorithms.
Digital signatures guarantee both integrity and authenticity of the message using an asymmetric key. The sender generates a message digest (e.g. using SHA1) and encrypts it using a private key. The receiver then decrypts using a public key and compares the message digest with a digest generated from the received message.
The Crypto.sign() function generates a digital signature using the SHA1 algorithm to create the digest, which is then subsequently encrypted using the RSA algorithm with a PKCS8 formatted private key.
The following are the various supported standards for each of the Crypto class methods.
| AES128, AES192, AES256 for encryption. |
PCKS#5 padding and Cipher Block Chaining.
|MD5, SHA1, SHA256, SHA512|
|sign()||SHA1 with RSA|
The Crypto class provides the following functions to encrypt and decrypt using the AES algorithm:
The following considerations should be noted:
The following is an example where Salesforce generates the initialization vector and encrypts a String and then subsequently decrypts the cipher:
// Generate an AES key for the purpose of this sample. // Normally this key should be stored in a protected custom setting // or an encrypted field on a custom object Blob cryptoKey = Crypto.generateAesKey(256); // Generate the data to be encrypted. Blob data = Blob.valueOf('Test data to encrypted'); // Encrypt the data and have Salesforce.com generate the initialization vector Blob encryptedData = Crypto.encryptWithManagedIV('AES256', cryptoKey, data); // Decrypt the data - the first 16 bytes contain the initialization vector Blob decryptedData = Crypto.decryptWithManagedIV('AES256', cryptoKey, encryptedData); // Decode the decrypted data for subsequent use String decryptedDataString = decryptedData.toString();
The Apex Crypto class provides support for Digital Signatures with the sign() method. The following considerations apply:
Utilities such as keytool or openSSL can be used to generate a certificate from which a private key can be extracted. The important thing to note is that the resulting private key must be in PCKS#8 format. For example:
// Generate your own certificate - subject information is redacted openssl req -x509 -nodes -subj "/C=XX/ST=XXX/L=XXX/CN=www.xxx.com" -days 365 -newkey rsa:1024 -keyout key.pem -out cert.pem // Output the private key onto the terminal in PKCS#8 format openssl pkcs8 -topk8 -nocrypt -in key.pem -outform PEM
If you have a presupplied certificate in PFX format:
// Convert PFX into PEM openssl pkcs12 -nodes -nocerts -in key.pfx -out key.pem // Output the private key onto the terminal in PKCS#8 format openssl pkcs8 -topk8 -nocrypt -in key.pem -outform PEM
Don't forget to remove the newline characters when storing the private key!
The following is sample code to sign a given input string:
String algorithmName = 'RSA'; String key = 'pkcs8 format private key'; // Decode the key from base64 to binary Blob privateKey = EncodingUtil.base64Decode(key); Blob input = Blob.valueOf('12345qwerty'); Crypto.sign(algorithmName, input, privateKey);
This article summarizes the cryptographic capabilities of the Force.com platform, including functions to encrypt and decrypt data using the AES algorithm as well as a number of functions to generate digests, message authentication codes and digital signatures.
These functions can then be used to protect the confidentiality, integrity and authenticity of data.