Reply
Contributor
Posts: 42
Registered: ‎08-01-2013

Re: Working php hash verification

[ Edited ]

@Renaissance

 

I understand that things change and are deprecated. It is extremely unreasonable for me to review their documentation every once in a while for changes. 

 

1) I have a full-time job. It's over 100 pages long and they have 4 different documentations. I don't have time to check and see what changed with their API. They should be giving us announcements via emails (and not just to our customers, the actual developers need to know this too).

 

2) Knowing AuthorizeNet I don't trust them to update their documentation. They've done a shitty job the past 5 years why would they be any better now? We literally have 4 different documentations of theirs with all conflicting information at this point:

 

https://developer.authorize.net/support/hash_upgrade/

https://developer.authorize.net/api/reference/index.html

https://www.authorize.net/content/dam/authorize/documents/SIM_guide.pdf

https://api.authorize.net/xml/v1/schema/AnetApiSchema.xsd

 

NONE of them had that x_sha2_hash parameter. One says 30 item hash, one says 3 item hash. What the fck do they want from us?!

 

3) I am implementing the Accept Hosted, but if anyone knows how the software cycle works you know you don't just blindy remove an older version. You phase it out. Something they failed to do here. And phasing it out doesn't mean release an email that it's leaving in 2 weeks. You give several months notice. I am keeping around SIM in my software as a legacy option, but encouraging they use the Accept Hosted. I know how a software cycle works, they don't. Which is sad because this is a multi-billion dollar company. You'd think they have some competence.

 

Again, not blaming you for any of this. You don't work there. Though I don't know why you'd want to be a certified developer for this place. There are so many better places to work.

 

After this whole debacle and incompetence and lack of wanting to help their customers I will be steering all my customers away from AuthorizeNet now and convincing them of some other solution. This isn't worth the technical debt (another term they'd learn if they got a degree in Software Engineering). I've already lost 3 work days on this when I could have be implementing something else. 

 

They clearly don't give a shit about us customers so why should we stay? I'll be talking with my product manager today about getting off this platform.

Member
Posts: 9
Registered: ‎01-14-2019

Re: Working php hash verification

[ Edited ]

I finally got the hash to match the "x_sha2_hash" value from the relay response.  But if I try to use the same C# method provide from https://developer.authorize.net/support/hash_upgrade/ to compute the hash for "x_fp_hash", I always get a response saying the transaction cannot be accepted.

 

So far, if I pass a md5 hash for x_fp_hash when creating a payment and on the relay response I compute the hash with sha512 and compare with x_sha2_hash, everything works.  

 

The only question is does the removal of md5 hash also means the x_fp_hash needs to be using sha512?

Contributor
Posts: 42
Registered: ‎08-01-2013

Re: Working php hash verification

Would you mind telling us how you got it to match? Which hash did you use? Which encoding? Thanks!

Member
Posts: 9
Registered: ‎01-14-2019

Re: Working php hash verification

This is the C# code, I added a check for the lenght of the key so that it would not break existing integration.

 

var computedHash = string.Empty;
if (key.Length == 128)
{
 
    var textToHash = string.Join("^",
                    request.Params["x_trans_id"],
                    request.Params["x_test_request"],
                    request.Params["x_response_code"],
                    request.Params["x_auth_code"],
                    request.Params["x_cvv2_resp_code"],
                    request.Params["x_cavv_response"],
                    request.Params["x_avs_code"],
                    request.Params["x_method"],
                    request.Params["x_account_number"],
                    request.Params["x_amount"],
                    request.Params["x_company"],
                    request.Params["x_first_name"],
                    request.Params["x_last_name"],
                    request.Params["x_address"],
                    request.Params["x_city"],
                    request.Params["x_state"],
                    request.Params["x_zip"],
                    request.Params["x_country"],
                    request.Params["x_phone"],
                    request.Params["x_fax"],
                    request.Params["x_email"],
                    request.Params["x_ship_to_company"],
                    request.Params["x_ship_to_first_name"],
                    request.Params["x_ship_to_last_name"],
                    request.Params["x_ship_to_address"],
                    request.Params["x_ship_to_city"],
                    request.Params["x_ship_to_state"],
                    request.Params["x_ship_to_zip"],
                    request.Params["x_ship_to_country"],
                    request.Params["x_invoice_num"]
                    );
 
    computedHash = HMACSHA512(key, $"^{textToHash}^");
    var sha2 = request.Params["x_SHA2_Hash"].ToString();
    return sha2 == computedHash;
}
else
{
    var md5er = MD5.Create();
    var bytes = System.Text.Encoding.ASCII.GetBytes(key + loginId + transactionId + amount);
    computedHash = String.Join("", md5er.ComputeHash(bytes).Select(s => s.ToString("X2")));
    return md5 == computedHash;
}

 

and the hashing method is what was provided from https://developer.authorize.net/support/hash_upgrade/

 

public static string HMACSHA512(string key, string textToHash)
 {
     if (string.IsNullOrEmpty(key))
         throw new ArgumentNullException("HMACSHA512: key", "Parameter cannot be empty.");
     if (string.IsNullOrEmpty(textToHash))
         throw new ArgumentNullException("HMACSHA512: textToHash", "Parameter cannot be empty.");
     if (key.Length % 2 != 0 || key.Trim().Length < 2)
     {
         throw new ArgumentNullException("HMACSHA512: key", "Parameter cannot be odd or less than 2 characters.");
     }
     try
     {
         byte[] k = Enumerable.Range(0, key.Length)
                     .Where(x => x % 2 == 0)
                     .Select(x => Convert.ToByte(key.Substring(x, 2), 16))
                     .ToArray();
         HMACSHA512 hmac = new HMACSHA512(k);
         byte[] HashedValue = hmac.ComputeHash((new System.Text.ASCIIEncoding()).GetBytes(textToHash));
         return BitConverter.ToString(HashedValue).Replace("-", string.Empty);
     }
     catch (Exception ex)
     {
         throw new Exception("HMACSHA512: " + ex.Message);
     }
 }

 

But using the same hashing method to create the hash for "x_fp_hash" got a "transaction cannot be accepted" response.

Trusted Contributor
Posts: 457
Registered: ‎11-05-2018

Re: Working php hash verification

@karenb,

What I am saying is that those 2 values are not contradictory values for the same thing. One value is for the fingerprint and one is for the verification. The fingerprint is the code I posted second. There is another user on another thread that has code that looks identical to mine except without strtoupper and that users code is working.

All I did was pull docs for the older methods and put it together piece by piece. I don’t use anything but the newer stuff cause I’m new to this. I do think my code will work for SIM/DPM for the fingerprint.

For the verification that is something to be worked out? Because it looks possible that unless your customer submits a value for every one of those parameters every time, your hash string function will have to put together a unique set of items.

@lightwave365,

I understand. It’s different strokes for different folks I guess. With all respect, this service has worked extremely well for me and I’m doing quite the opposite. I’m steering every customer in ecommerce that I get towards this service. This is the only provider I’ve used, so I admittedly have nothing to compare to. It may be a case of ignorance is bliss, just maybe, but I see no reason not to use what works so well for me.
But yes, there is a lot to this and I can see it getting overwhelming when you have many customers all using different methods.

My check just came. Best of luck to everyone until next time.
Contributor
Posts: 42
Registered: ‎08-01-2013

Re: Working php hash verification

[ Edited ]

@xero

 

This may seem odd but can you provide all the test data that you used so I can place the same data in my implementation and see if what I coded is correct and has your output? I'm using Java libraries for the hashing so I assume they are correct since they worked for the original MD5 but maybe it's handling something wrong.

 

Like give me the concatenated hash, the key, and the output.

 

Again, this surprises me that in the guide they don't provide input and output in their examples. Only input. Which is pretty useless.

Member
Posts: 9
Registered: ‎01-14-2019

Re: Working php hash verification

@lightwave365

 

using the following key and text should produce this x_SHA2_Hash.  Hope this help.

 

key  "9C5A4D2AFE1D1D5DB3A8FC4C95CDCF49E2B052B4220D0624C54C1C662194BDEF8FE0EA27B313FA62328D9500D123B9DD3CE06644508803ACD04DAEDB24C5D122"

 

text = "^0^false^3^^^^P^^^1.99^^^^^^^^^^^^^^^^^^^^^"

 

 

x_SHA2_Hash= "4038397293CE5DBBFD5AD21B2F96FF5B6E32EA9F56D310AA95D1D091EBEAD1C35FE5AF96111D7911B2816FCE0DBA2D41A5BD268F766183DC8F3B750B22F68E16"

 

 

 

 

Trusted Contributor
Posts: 457
Registered: ‎11-05-2018

Re: Working php hash verification

@xero,

For the fingerprint you use a different string than what is on the upgrade link. That link is for the new API and not DPM/SIM. The second php example I posted on this thread has the string for the fingerprint for those methods. I haven’t tested it but it should work. Another user has the same string and has posted that their fingerprint is working. And for your other question, as I understand it at some later date both MD5 values will be axed in favor of sha512
Member
Posts: 9
Registered: ‎01-14-2019

Re: Working php hash verification

Finally got the x_fp_hash as well.  It turns out the x_fp_timestamp I was using in my test was too old, it has to be with in 15 mins difference from authorize's server.  After I updated my code to get the current time it worked.

Member
Posts: 9
Registered: ‎01-14-2019

Re: Working php hash verification

This is my c# test code incase anyone is interested 

 

var epoTime = (int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;
 
const string amount = "1.99", x_fp_sequence = "2627";
 
var x_fp_timestamp = epoTime.ToString();
 
string textToHash = $"{loginId}^{x_fp_sequence}^{x_fp_timestamp}^{amount}^USD";
 
var x_fp_hash = HMACSHA512(key, textToHash);