2

Why am I getting a different mac value from Salesforce's Apex vs C#?

I have the following C# code to generate a signature:

using (var hmacSha512 = System.Security.Cryptography.HMACSHA512.Create())
{
    byte[] payload = System.Text.Encoding.UTF8.GetBytes("payload");
    hmacSha512.Key = System.Text.Encoding.UTF8.GetBytes("key");
    byte[] macBytes = hmacSha512.ComputeHash(payload);
    string mac = BitConverter.ToString(macBytes).Replace("-", string.Empty).ToLower();
    Console.WriteLine(mac);
}

And I've tried to implement the corresponding code in Apex:

Blob payload = Blob.valueOf('payload');
Blob key = Blob.valueOf('key');
Blob macBlob = Crypto.generateMac('hmacSHA512', payload, key);
string mac = EncodingUtil.convertToHex(macBlob);
System.debug(mac);

But the results I get are different:

C#:    2f3902cd1626fa7fdfb67e93109f50412ad71531
Apex:  185beceee65a5ed7e43f7cc98530bfab1b0d00679488a47225255d04594fd7f17ed6908e7a08df57ac14c9e56c2fdef83ee9adaf9df2ff9f61465898c5d78c00

As you can see the Apex result is significantly longer than the C# equivalent. Naturally, I decided to check that Blob->Hex works as I expect it by also printing the payload and key values in hex:

// C#:
Console.WriteLine(BitConverter.ToString(payload).Replace("-", string.Empty).ToLower());
Console.WriteLine(BitConverter.ToString(hmacSha512.Key).Replace("-", string.Empty).ToLower());

// Results:
// 7061796c6f6164
// 6b6579

// Apex:
System.debug(EncodingUtil.convertToHex(payload));
System.debug(EncodingUtil.convertToHex(key));

// Results:
// 7061796c6f6164
// 6b6579

So the blob values are what I expect, and conversion to hex works (unsurprisingly) as I expect.

If I try the same payload and key combination on this online service, I get the same value as Salesforce. Even Java is the same as Salesforce. This leads me to think the C# implementation is incorrect, but I can't understand why.

I thought that perhaps I needed to manually hash SHA512 and pass it into HMCSHA512, but this doesn't make a difference to the length.

What am I doing wrong in my C# implementation?

ProgrammingLlama
  • 36,677
  • 7
  • 67
  • 86

1 Answers1

0

It seems that I actually wanted to use KeyedHashAlgorithm with "HmacSHA512":

using (var hmacSha512 = System.Security.Cryptography.KeyedHashAlgorithm.Create("HmacSHA512"))

I realised that this didn't work in .NET Core (it throws an exception when running the Create method), so I changed it to this:

using (var hmacSha512 = new System.Security.Cryptography.HMACSHA512())

I'm not really sure why this provides a different result, but sure enough when I run it I get the same result as in Apex:

185beceee65a5ed7e43f7cc98530bfab1b0d00679488a47225255d04594fd7f17ed6908e7a08df57ac14c9e56c2fdef83ee9adaf9df2ff9f61465898c5d78c00
ProgrammingLlama
  • 36,677
  • 7
  • 67
  • 86