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
1 ACCEPTED SOLUTION

Accepted Solutions

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');

View solution in original post

kabutotx
Regular Contributor
22 REPLIES 22
I would venture that your issue is one or more of the following, with a disclaimer that I have never used sim:

-for MD5, as I understand it, you created part of your string in the merchant interface. You do not do that for the new hash. The sequence is an arbitrary number that you make up.

-the above creates a new step in the process where you have to pass the value of your sequence in the request (because Authorize doesnโ€™t have it in the interface anymore)
Renaissance
All Star
A third problem is you are missing a caret at the beginning of your string.

@Renaissance wrote:
A third problem is you are missing a caret at the beginning of your string.

The Do I need to upgrade my transaction... linked in the first post and the SIM Guide (page 30) do not specify a caret at the beginning of the string used to generate the hash.  Both show the format to be "x_login^x_fp_sequence^x_fp_timestamp^x_amount^".

 

I am having this exact same problem, only with a Java implementation.  Ours is also currently working by generating an MD5 hash using the above string and the Transaction Key, and passing that in the x_fp_hash field.  However, when SHA512 is used with the same string above and the Signature Key instead, I get Error 99 every time (The server-generated fingerprint does not match the merchant-specified fingerprint in the x_fp_hash field).

 

Interesting that the Do I need to upgrade my transaction... page says the Signature Key needs to first be converted to binary before computing SHA512 hash but the SIM Guide does not.  I have tried it both ways and still always get Error 99.  What are we missing here?

 


@Renaissance wrote:
A third problem is you are missing a caret at the beginning of your string.

@Renaissance I appreciate the input, however, for the initial fingerprint, a leading ^ was not necessary in the MD5 implementation nor is called for in the SHA512 implentation, according to here ( https://support.authorize.net/s/article/Do-I-need-to-upgrade-my-transaction-fingerprint-from-HMAC-MD...

 

Taken from link ... 

For example, if we presume an API Login ID of "authnettest", a sequence number of "789", a timestamp of "67897654," an amount of "10.50", and no currency code, the hash input would look like this:

authnettest^789^67897654^10.50^

 

The leading ^ instruction comes from here ( https://developer.authorize.net/support/hash_upgrade/ ), this page discusses how to validate the AuthNet response from the Hosted Payment Form by comparing the transHashSHA2, with a locally calculated value... however, using SHA512 (and the new signature key method) I haven't been able to successfully submit the initial SIM request ... to load the Hosted Payment Form.

 

 

@Renaissance I appreciate your time and your input, however...


@Renaissance wrote:
-for MD5, as I understand it, you created part of your string in the merchant interface. You do not do that for the new hash. The sequence is an arbitrary number that you make up.

In the MD5 method, we used a Transaction Key for the HMAC key.  The Transaction Key was pulled from the merchant interface and used directly in the HMAC function, without any changes made.  The new hash method uses a Signature Key that is also taken from the merchant interface, however it is not used directly in the HMAC function.  It is, in its inital state, a hex string, that is to be converted to binary prior to using as the key in the HMAC function.

Taken from ( Do I need to upgrade my ... )
It is important to note that the Signature Key is presented in the Merchant Interface, in hexadecimal format. You will need to convert the Signature Key to binary format before calculating the HMAC-SHA512 hash.
...
You would then hash this input with the HMAC-SHA512 algorithm, using the binary-encoded Signature Key as the HMAC key.

It is my understanding that the toBinary() function would accomplish this in CF. 


@Renaissance wrote:
-the above creates a new step in the process where you have to pass the value of your sequence in the request (because Authorize doesnโ€™t have it in the interface anymore)

I believe that you are using the term sequence to refere to the Key (Transaction vs Signature), I've outline (as I understand them) the difference between these two values and the MD5 vs SHA512 methods.  To be clear, both methods, MD5 and SHA512, require a sequence to both be passed as a form field key/value pair and used inte the creation of the HMAC fingerprint... this is supposed to be a value that you create (generally an invoice number or other unique value) 

 

  • The unique merchant-generated sequence number (x_fp_sequence);

 

You are right. I've been helping people with this. I don't use SIM/DPM and the other methods have a leading caret.

 

I am not versed in this, but am I not correct that using MD5 you had to enter a number in the merchant inferface, and that number was going to be used in calculating the hash? I keep hearing of "the merchant will lose the ability to put xzy in the merchant interface".  I may be totally off.

 

That was what I was referring to as possibly your problem. From what I read, you don't use the value inputted in the merchant interface. You just randomly generate a number on your end and use it. So you could just do "123" and use that for the sequence. This is totally separate from the signature key or transaction key.

 

Then you pass along the 123 in the request.  I won't be on here anymore today, but I'll see what you've got later on. 


@Renaissance wrote:

... but am I not correct that using MD5 you had to enter a number in the merchant inferface, and that number was going to be used in calculating the hash? I keep hearing of "the merchant will lose the ability to put xzy in the merchant interface".  I may be totally off.

 

That was what I was referring to as possibly your problem. From what I read, you don't use the value inputted in the merchant interface. You just randomly generate a number on your end and use it. So you could just do "123" and use that for the sequence. This is totally separate from the signature key or transaction key.


From MD5 Hash End of Life....

Phase 1 - Starting later this month to early February 2019, we will remove ability to configure or update MD5 Hash setting in the Merchant Interface. There are no changes to the existing API response.

 

As I read it, the change in the Merchant Interface is that the user will no longer be able to enable/update MD5 Hash as an authorized method.  So they are disabling the option of selecting MD5. 

 

You are correct, we are not using the MD5 Hash string inputed in the Merchant Interface > MD5-Hash, that is/was used to encrypt the responses from AuthNet, not for calculating the signature when submitting a request for load of the Hosted Payment Form.  We are using the key values assigned by AuthNet.  The Signature Key, once made binary, is the new version of the old Transaction Key.  

 

The usage of sequence itself hasn't changed and is a unique value used within the hashed string and passed as a form element.  Taken from Do I need to upgrade ...

  • The API Login ID (x_login);
  • The unique merchant-generated sequence number (x_fp_sequence);
  • The transaction's timestamp in UNIX Epoch time, i.e. how many seconds have passed since Midnight UTC on January 1, 1970 (x_fp_timestamp);
  • The transaction amount (x_amount);
  • The currency code (x_currency_code), which should be blank if no currency code is submitted.

For example, if we presume an API Login ID of "authnettest", a sequence number of "789", a timestamp of "67897654," an amount of "10.50", and no currency code, the hash input would look like this:

authnettest^789^67897654^10.50^

The only changes, as I read them, are 

  • use SHA512 instead of MD5
  • use binary converted Signature Key, instead of plain text Transaction Key

everything else is supposed to be the same, even the field that the hash/fingerprint is submitted via and AuthNet will determine which method you've used.

 

I am still working on a Coldfusion solution, however since I am beginning to believe this has more to do with the underlying Java libraries than my implimentation, I have put into place a solution using PHP 5.3 to generate the fingerprint and pass back to CF for use in the existing calls.  This works.  Eventually, we will migrate away from SIM/DPM to the API, however for now... 

 

I make a cfhttp call to the PHP form, that receives the necessary pieces to calc the fingerprint and returns the timestamp and fingerprint for use by the existing CF process.

 

I have read that users have had success using hex2bin(), base_convert(), and pack()... since hex2bin is not available in 5.3, I had to try the other two.  The HMAC-SHA512 fingerprint calculated using base_convert() received Error 99, however the HMAC-SHA512 fingerprint calculated using pack() was successful and I was able to load the Direct Payment Form.

mojenals
Member

I was unable to develop a fully CF/Java implementation ... time simply too limited at this point and with a working solution in PHP, having to mark it as done step away.