I need to create a signature in order to send a request to CyberSource. I have the following Java code, that works perfectly:

String signatureString = "Test";

final Mac sha256HMAC = Mac.getInstance("HmacSHA256");
final SecretKeySpec secretKey = new SecretKeySpec(

Base64.getDecoder().decode("LZjfTQi8uxEn5VFI3S4Ml+8UY4y3b2F0aP8c8WuiQtY="), "HmacSHA256");
final byte[] hashBytes = sha256HMAC.doFinal();
final String signatureB64 = Base64.getEncoder().encodeToString(hashBytes);
System.out.println(signatureB64.toString()); //nbXkkkM3GuPp8YEIb7JnAj4IrDy0YC7t3Pl/cJxStW0=

I tried to make the same on Apex, but it shows me different result:

String signatureString = 'Test';
System.debug(generateHmacSHA256Signature(signatureString, 'LZjfTQi8uxEn5VFI3S4Ml+8UY4y3b2F0aP8c8WuiQtY=')); //5zJnHFYz6HklMZ8vR4rf7UJfjrumiexZeYDgsuErrk=

public static String generateHmacSHA256Signature(String input, String secretKey) {
    String algorithmName = 'HmacSHA256';
    Blob mac = Crypto.generateMac(algorithmName, Blob.valueOf(input), Blob.valueOf(Secretkey));
    String macUrl = EncodingUtil.base64Encode(mac);
    return macUrl;

So Java returns nbXkkkM3GuPp8YEIb7JnAj4IrDy0YC7t3Pl/cJxStW0= and Apex 5zJnHFYz6HklMZ8vR4rf7UJfjrumiexZeYDgsuErrk= results are different.

How can I get the same result, as in Java? Any help very appriciated.

1 Answer 1


Your Apex code just misses the base64 decoding step on your secret key. If you change the call to generateMac() to this:

Blob mac = Crypto.generateMac(algorithmName, Blob.valueOf(input), EncodingUtil.base64Decode(Secretkey));

You'll get back

10:39:43:003 USER_DEBUG [2]|DEBUG|nbXkkkM3GuPp8YEIb7JnAj4IrDy0YC7t3Pl/cJxStW0=

  • 2
    I wasted almost all day to try different combinations of EncodingUtil.base64Decode and Blob.valueOf, but on more complicated input... What's a fresh view mean! Commented Mar 19, 2019 at 14:44

You must log in to answer this question.

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