Skip to main content

Webhook Security

Branch uses AES with CBC mode and PKCS5 padding to encrypt sensitive data.

All sensitive data is prepended with a random initialization vector(IV) to avoid dictionary attacks.

Decryption mechanism needs to be implemented on the client side in order to read sensitive data.


Branch provides the AES key in BASE64 format. Clients need to be sure that they have the key provided by Branch before implementing the solution on their end.


Implementation can be summed up in two steps.

Decryption service#

This service accepts the BASE64 encrypted sensitive data and the BASE64 key. The service eventually calls the AES Utility function after getting the byte values.

public class DecryptionService {
* Decrypts a user provided encrypted value with a user provided key
* @param base64EncryptedValue is the user provided base64 encrypted value
* @param base64Key is the base64 encoded key string
* @return UTF8 encoded value string
public String decrypt(String base64EncryptedValue, String base64Key) {
byte[] encryptedByteValue = Base64.getDecoder().decode(base64EncryptedValue);
byte[] key = Base64.getDecoder().decode(base64Key);
byte[] decryptedValue = AESUtil.decrypt(encryptedByteValue, key);
return new String(decryptedValue, UTF_8);

AES Utility function#

This utility function is used to decrypt the value provided by the service function.

public class AESUtil {
private final String ALGORITHM = "AES";
private final String CIPHER_TRANSFORMATION = "AES/CBC/PKCS5Padding";
public byte[] decrypt(byte[] value, byte[] key) {
Cipher cipher = Cipher.getInstance(CIPHER_TRANSFORMATION);
// Get the random iv from value
byte[] iv = ArrayUtils.subarray(value, 0, cipher.getBlockSize());
byte[] encryptedValue = ArrayUtils.subarray(value, cipher.getBlockSize(), value.length);
IvParameterSpec ivParam = new IvParameterSpec(iv);
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, ALGORITHM), ivParam);
return cipher.doFinal(encryptedValue);