hmac sha 256 in Salesforce?

Hi,

I'm trying to implement the hmac sha256 example from the documentation in Salesforce Apex, but I am not able to reproduce the base64 value.

This is the example HTTP request from the documentation:

POST /v1/cases HTTP/1.1
Host: rms-world-check-one-api.thomsonreuters.com
Date: Tue, 07 Jun 2016 20:51:35 GMT
Content-Type: application/json
Content-Length: 88
{
"caseId": "my customer ID",
"name": "John Doe",
"providerTypes": ["WATCHLIST"]
}

According to the example, the following input should be used for the hmac function:

(request-target): post /v1/cases
host: rms-world-check-one-api.thomsonreuters.com
date: Tue, 07 Jun 2016 20:51:35 GMT
content-type: application/json
content-length: 88
{
"caseId": "my customer ID",
"name": "John Doe",
"providerTypes": ["WATCHLIST"]
}

I implemented the function (as shown below), but keep getting different values. I even tried to alter the spaces and the line endings, but never matched the value, which is shown in the example:

"Given the above signing text, if a secret key of “1234” is used, the computed HMAC-SHA256 value would beDA26D7F5BFF89A100D1A597AA015099FC55DD3130F023E952BFBE3A6949F322A when printed using hex encoding, or2ibX9b/4mhANGll6oBUJn8Vd0xMPAj6VK/vjppSfMio= when printed using base64 encoding."

[...]

String testString = '(request-target): post /v1/cases\n'
+'host: rms-world-check-one-api.thomsonreuters.com\n'
+'date: Tue, 07 Jun 2016 20:51:35 GMT\n'
+'content-type: application/json\n'
+'content-length: 88\n'
+'{\n'
+'"caseId": "my customer ID",\n'
+'"name": "John Doe",\n'
+'"providerTypes": ["WATCHLIST"]\n'
+'}';

String testKey = '1234';
String algorithmName = 'HmacSHA256';
Blob hmacData = Crypto.generateMac(algorithmName, Blob.valueOf(testString), Blob.valueOf(testKey));
return EncodingUtil.base64Encode(hmacData);

[...]

In this case, the base64 value was "V9d9dkg2aS1J0P/7GVPdC34ddLMdrRixtt6mf9xsJ+Q="

Line endings should be fine, according to the Salesforce Apex Language Reference. \n should be a LF Line ending.

Source: https://resources.docs.salesforce.com/sfdc/pdf/salesforce_apex_language_reference.pdf - Page 29

Salesforce docs show, the used method is fine: Crypto.generateMac

Source: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_restful_crypto.htm

Do you have any idea what is wrong here? Do I have an error in my spacing or something like that? I just want to implement the example in Salesforce Apex Code.

Thanks in advance.

Best Answer

  • Hi @raphael.rugova,

    I recreated the example in the Documentation with special attention to detailing exactly how I got my results....

    I attached a screen shot of what I did... a couple Notes:

    1. The body of the message uses Unix LF and not DOS CR/LF (it's documented but easily overlooked if you cut&paste the example.
    2. I use Notepad++ to view the message. This helps by showing there are 2 spaces before some of the lines and the LF, plus the count of bytes to confirm I've correctly copied the message body
    3. I use Visual Studio C# to produce my results, using the HMACSHA256 code example from the Microsoft Documentation, see code below.

    Hope this helps,

    Brian

            // Combine the data signature and the API secret key to get the HMAC
    // This is the Microsoft HMACSHA256 code copied from the documentation
    public static string generateAuthHeader(string dataToSign, string apisecret)
    {
    byte[] secretKey = Encoding.UTF8.GetBytes(apisecret);
    HMACSHA256 hmac = new HMACSHA256(secretKey);
    hmac.Initialize();


    byte[] bytes = Encoding.UTF8.GetBytes(dataToSign);
    byte[] rawHmac = hmac.ComputeHash(bytes);
    Console.WriteLine("---rawHmac---");
    string hex = BitConverter.ToString(rawHmac).Replace("-","");
    Console.WriteLine(hex);
    return(Convert.ToBase64String(rawHmac));
    }

Answers