cancel
Showing results for 
Search instead for 
Did you mean: 

Coldfusion SIM HMAC-SHA512 Update

Hi all... I currently have a working SIM MD5 solution and am updating to SHA512.  I believe that I have walked through the necessary steps as outlined here ( https://support.authorize.net/s/article/Do-I-need-to-upgrade-my-transaction-fingerprint-from-HMAC-MD... ), however continue to receive an Error Code 99.

 

Essentially, the only changes are, as I read them
 -- to request a Signature Key, change to binary, use this as the HMAC key
 -- change the algorithm from HMACMD5 to HMACSHA512

 

MD5 Solution:
<cfset digest=HMAC("#authNetLogin#^#sequence#^#fp_timestamp#^#x_amount#^","#authNetTrnxKey#","HMACMD5") />

SHA512:
<cfset authNetHexSignatureKey = "REMOVED_FROM_CODE" />
<cfset authNetBinarySignatureKey = toBinary(authNetHexSignatureKey) />
<cfset digest=HMAC("#authNetLogin#^#sequence#^#fp_timestamp#^#x_amount#^","#authNetBinarySignatureKey#","HMACSHA512")>

 

The existing Error 99 tool ( https://developer.authorize.net/api/reference/responseCode99.html ) appears to be for use in the old MD5 method.  Is there another tool for this?

 

I have looked at the data being posted using the dump tool here ( http://developer.authorize.net/bin/developer/paramdump ) and everything LOOKS ok.

 

Any assistance would be appreciated.

Thanks.

mojenals
Member
22 REPLIES 22

Here is code that works in CF/Lucee.

authSignature = the signature key

message = Built message from API, CIM, AIM or whatever.

key=binaryDecode(authSignature, "hex" );
hashResult = hmac(message, key, 'HMACSHA512');
kabutotx
Regular Contributor

Not sure if you still need this, but I was able to get this to work. The signature key is in a hex format and the toBinary function is expecting base64 data. The binaryDecode function though allows you to specify that the data is hex. So your HMAC script should look like this:

 

<cfset authNetHexSignatureKey = "REMOVED_FROM_CODE" />
<cfset authNetBinarySignatureKey = binaryDecode(authNetHexSignatureKey, "hex") />
<cfset digest=HMAC("#authNetLogin#^#sequence#^#fp_timestamp#^#x_amount#^","#authNetBinarySignatureKey#","HMACSHA512")>

 

This worked for me.

deanlaw
Contributor

I appreciate your help @kabutotx and @deanlaw.

 

@kabutotx , the use of binaryDecode() was the solution.

@deanlaw , thank you for pointing out the difference between binaryDecode() and toBinary()

 

I have updated our CF code and successfully removed the PHP script.

 

Thanks!

 

mojenals
Member

Hi @deanlaw 

 

What version of CF are you using?  I'm attempting to get this working also and so far no go with CF 10 BUT

 

I'm using Auth.net sandbox

I'm also just using what is called the Silent Post Url which means auth.net posts data to my site and so I'm attempting to generate this hashed string and compare that to the value from Auth.net form field X_SHA2_HASH.

 

It's not very clear what the hashed sting should be but I believe it needs to be constructed of the 30 form fields separated by ^ and maybe a trailing ^ or prepended ^ or both..i've tried all 4 options and so far my result doesn't match but no clue if the problem is CF10 or auth.net sandbox or me.  So any clues would be appreciated.

It should work with CF 10+.  The hmac function is the newset and CF 10+. 
(There is a CF_HMAC addon available that might work for older CF) I see you are following the other thread on the Silent Post URL.  I am using the API version for CF.  Each API builds a different message, so check with that API.

@MinneSnowtainI am using ACF 2016. I also have ACF 11 running on another server, which I have not tested yet, but it should work the same.

 

If you look at this guide, SIM Guide, starting at the bottom of page 29, it outlines what the fingerprint is comprised of. "x_login^x_fp_sequence^x_fp_timestamp^x_amount^". There is also a 5th field that you can use, which is for currency, which looks like this: "x_login^x_fp_sequence^x_fp_timestamp^x_amount^US" (notice, no trailing carat). You can see this in example 2 on page 30. You would then use your binary converted Session Key (not your Transaction Key) to generate the SHA512 hash.

 

<cfset authNetHexSignatureKey = "REMOVED_FROM_CODE" />
<cfset authNetBinarySignatureKey = binaryDecode(authNetHexSignatureKey, "hex") />
<cfset digest=HMAC("#x_login#^#x_fp_sequence#^#fp_timestamp#^#x_amount#^","#authNetBinarySignatureKey#","HMACSHA512")>

 

Also, after generating the digest variable above, I submit it using the x_fp_hash field. I don't know if this is different using the Silent Post feature.

 

Hope this helps.

Thank you @deanlaw  and @kabutotx 

 

So @kabutotx did you try using CF10? or are you just guessing that it should work?

 

Unfortunately I'm not using the API and I'm not sending this hashed result but comparing my hash result with what I get posted (just a regular ole form post) from auth.net.  Unfortunately the string that Auth.net uses to hash is a bit of a mystery to me which makes this harder yet.

Didn't try CF 10 but hmac builtin function was added to CF at that version.

I assume you are using the old SIM API, so follow @deanlaw posted above.

I am happy to report that my posted signature TO auth.net is valid using:

 

<cfset authNetBinarySignatureKey = binaryDecode(x_secret_key,"hex") />
<cfset x_fp_hash=HMAC("#x_login#^#x_fp_sequence#^#x_fp_timestamp#^#x_amount#^#x_currency_code#","#authNetBinarySignatureKey#","HMACSHA512")>

 

Now if only I could validate what sandbox returns back to me via the silent post.

 

This now confirms there is something wrong with the string I create that is hashed.

 

So far this is what I've tried

<cfset stringToHash="">
<cfset stringToHash="#stringToHash##form.x_trans_id#">
<cfset stringToHash="#stringToHash#^#form.x_test_request#">
<cfset stringToHash="#stringToHash#^#form.x_response_code#">
<cfset stringToHash="#stringToHash#^#form.x_auth_code#">
<cfset stringToHash="#stringToHash#^#form.x_cvv2_resp_code#">
<cfset stringToHash="#stringToHash#^#form.x_cavv_response#">
<cfset stringToHash="#stringToHash#^#form.x_avs_code#">
<cfset stringToHash="#stringToHash#^#form.x_method#">
<cfset stringToHash="#stringToHash#^#form.x_account_number#">
<cfset stringToHash="#stringToHash#^#form.x_amount#">
<cfset stringToHash="#stringToHash#^#form.x_company#">
<cfset stringToHash="#stringToHash#^#form.x_first_name#">
<cfset stringToHash="#stringToHash#^#form.x_last_name#">
<cfset stringToHash="#stringToHash#^#form.x_address#">
<cfset stringToHash="#stringToHash#^#form.x_city#">
<cfset stringToHash="#stringToHash#^#form.x_state#">
<cfset stringToHash="#stringToHash#^#form.x_zip#">
<cfset stringToHash="#stringToHash#^#form.x_country#">
<cfset stringToHash="#stringToHash#^#form.x_phone#">
<cfset stringToHash="#stringToHash#^#form.x_fax#">
<cfset stringToHash="#stringToHash#^#form.x_email#">
<cfset stringToHash="#stringToHash#^#form.x_ship_to_company#">
<cfset stringToHash="#stringToHash#^#form.x_ship_to_first_name#">
<cfset stringToHash="#stringToHash#^#form.x_ship_to_last_name#">
<cfset stringToHash="#stringToHash#^#form.x_ship_to_address#">
<cfset stringToHash="#stringToHash#^#form.x_ship_to_city#">
<cfset stringToHash="#stringToHash#^#form.x_ship_to_state#">
<cfset stringToHash="#stringToHash#^#form.x_ship_to_zip#">
<cfset stringToHash="#stringToHash#^#form.x_ship_to_country#">
<cfset stringToHash="#stringToHash#^#form.x_invoice_num#">

 

that string did not result is a match

 

same string as above but added

<cfset stringToHash="#orgstringToHash#^">

it did not match

 

same as orignal string but added

<cfset stringToHash="^#orgstringToHash#">

it did not match

 

same as orignal string but added

<cfset stringToHash="^#orgstringToHash#^">

it did not match

 

 

 

 

Per page 73 It is ^field and an ending ^.  So each of your form. field should start with a ^ and then the data and the whole thing (string of all form fields) should end with a ^.