function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Brendan CBrendan C 

Reproduce Python hmac process?

Hello!

I am attempting to mirror a specific process for generating an hmac (using SHA-256) that is currently being done in Python.

The problem is as follows,

1) In Python - you have a two step process for generating an hmac/signature
2) First step - you initialize a new hmac object with your secret key
3) Second step - you call an UPDATE method with the specific string you want to use for your signature (see example below)
# Create a HMAC-SHA256 instance and initialize it with your secret 
hmac = hmac.new("yoursecretkey", digestmod=hashlib.sha256)
# Update the instance with your sig string
hmac.update("yourinputstring")
sig = hmac.hexdigest()
4) You then can call hmac.hexdigest and get a hex encoded signature

The problem is - in Salesforce, there is a single method, Crypto.generateMac, that takes three arguments:

a) The algorithm (sha-256)
b) The input string
c) Your secret key

Running this method with the same string/secret key will net out a different result than running the process in Python.

I don't know enough about hmac/SHA-256 to know what the hmac.new vs hmac.update methods are doing - but I'm hoping to reproduce the process and get the same results in Salesforce.

Any help/thoughts you could provide would be very helpful
Best Answer chosen by Brendan C
Brendan CBrendan C
Figured out what I was doing wrong - it was a fat finger typo on the URL encoding!

So to confirm - the "generateMac" method should yield the exact same results as Python's hmac class.

Here's what my code ended up looking like (note that the final output needed to be in hex in my case):
 
private static String generateHmacSHA256Signature(String input, String secretKeyValue) {
    String algorithmName = 'hmacSHA256';
    Blob hmacData = Crypto.generateMac(algorithmName, Blob.valueOf(input), Blob.valueOf(secretKeyValue));
    return EncodingUtil.convertToHex(hmacData);
}

 

All Answers

Brendan CBrendan C
Forgot to add link to relevant documentation in Python:

https://docs.python.org/2/library/hmac.html
Chris GaryChris Gary
Hi There,

One you create your blob using Crypto.generateMac,  you will get back a Blob Data type.  You need to run that result through the EncodingUtil.convertToHex() method to get the Hex version of the Blob.  EncodingUtil.convertToHex is a static Method, so you should be able to do somthing like
String hexResult = EncodingUtil.converttoHex(Crypto.generateMac('hmacSHA256',Blob.valueOf('yourinputstring'),Blob.valueOf('yousecretkey')));

Just taking a crack at this one. But if it works for you, please mark as this answer solving your question!

Thanks,
Brendan CBrendan C
@Chris - thanks for the suggestion, I am already doing the hex conversion at the end, so I'm getting a string that's the right length, just wrong :(
Brendan CBrendan C
Figured out what I was doing wrong - it was a fat finger typo on the URL encoding!

So to confirm - the "generateMac" method should yield the exact same results as Python's hmac class.

Here's what my code ended up looking like (note that the final output needed to be in hex in my case):
 
private static String generateHmacSHA256Signature(String input, String secretKeyValue) {
    String algorithmName = 'hmacSHA256';
    Blob hmacData = Crypto.generateMac(algorithmName, Blob.valueOf(input), Blob.valueOf(secretKeyValue));
    return EncodingUtil.convertToHex(hmacData);
}

 
This was selected as the best answer