OKCOOL

Back

PHP MD5 not the same as .NET MD5

I’m in the process of writing the API for our fancy new web management platform (I think you’ll like it, watch this space).

One of the security features I’ve implemented is an integrity check for the data being posted across the wire. I won’t go in to the details of it but all I need to say is I’m using MD5 to compute a hash of the posted data.

My trouble came tonight when trying to get an MD5 generated in .NET to match the one being passed to it by PHP. In PHP the md5 function is very basic, but it’s a bit more involved in .NET.

Finally though, I found the solution. Here’s the code:

It would seem the key thing to get them to match is to use the UTF7Encoding. Most of the MD5 examples around the web for .NET though seem to indicate you should use UTF8.

I’d be interested to know if this is the right way to go about cracking this nut, but for now, it’s the only way I can find.

  • Tom
  • 23 April 2008
  • 8 comments

Comments

victorantos

said on 24 April 2008

That’s what I’m looking for, I was using
System.Security.Cryptography.HMACMD5 h = new System.Security.Cryptography.HMACMD5(); h.ComputeHash(data2);

but it doesn’t match with php generated hash

Morten K. Poulsen

said on 24 April 2008

The MD5 algorithm digests blocks of 512 bits (64 bytes). It does not interpret the data in any way. So if you have a string of characters, you must represent them in the same way (US-ASCII, UTF-8, ISO-8859-15, …) on each system, before hashing them. Otherwise you are hashing different byte sequences, and will – naturally – get different hash results.

Best regards,
Morten K. Poulsen

Lee Kelleher

said on 22 May 2008

Hidden away under an un-intuitive namespace is…

System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(”hashMe”, “MD5″)

The outputted MD5 is in uppercase, so just add a .ToLower().

Dennis Bottaro

said on 27 May 2008

This works perfectly when the incoming data is only alphanumeric. I have run into trouble when the incoming has characters other than a-z,A-Z,1-0. For example with this string “t0ph@t” php’s MD5 comes up with “aec0cbe6302f25d8cce350e324704a52″ while the version here comes up with “0ad1d3db5ba9b96f248816794b579fb1″

I have not tested changing the encoding, but wondered if anyone else ran across this same problem. If I come up with a resolution, I will post it back here.

RyanTheGreat

said on 11 June 2008

I’m not a .NET programmer, but I may be able to address a few of the comments here. Starting with the article itself, I don’t believe that UTF-7 is the actual answer to your problems, but rather, a means of consistency for the data encoding before encryption. When computing a hash from a string, the data encoding is only important as to the extent of consistency in characters. What I mean by this is, if a string is being transmitted encoded as UTF-8 encrypted by md5 and compared against a ISO-8859-1 encoded string with the same characters it may or may not be equal due to the encoding, converting the strings in this example to UTF-7 is just a means of ensuring they are represented equivalently.

As for the comment by victorantos, the reason your output is not equivalent to php’s md5 without even knowing any .NET C# syntax is clear from the function call. HMAC-md5 (or any other HMAC-hash function) provides an additional functionality above the basic md5 hashing algorithm. The HMAC- algorithms are frequently used in API’s in which the transmitting parties share a secret key K and hash the data along with XORing K against 2 sets of data to explain simply. The basic explanation is that is the wrong function to use, you must use the appropriate md5 function for your language.

Finally, to address the comment of Dennis Bottaro, this is because of the use of UTF-7 encoding in this example to hash the data. UTF-7 is actually poor choice for encoding data before hashing due to the representation of most non-alphanumeric characters as you have suggested above. This, compared to non-UTF-7 encoded data in the php md5() function will obviously yield different results due to the representation of the non-alphanumeric data. To reiterate from before, the way to fix this is to make sure the encoding does not change, and also, make sure you are using the appropriate function within your languages function set.

-Ryan

Tom

said on 18 July 2008

Thanks for everyone’s comments. I understand the problem much better now. I’ve experienced problems as suggested with UTF7 but have used the UTF8 encoding and at the moment it seems to be working.

MD5 in PHP works exactly as it should (don’t believe the hype!) | Thomas David Wright

said on 4 August 2008

[...] don’t pay any heed whatsoever to the whisperings that abound the wonderful interweb. Hmmm… Maybe ‘abound’ isn’t the right [...]

Amrox

said on 14 December 2008

I think UTF7 is not the answer!!!
I am using Arabic (I think the problem will be there for other languages)
I am trying to build a login based on VBulletin its working for English but Arabic its not working I tried all types of encoding:
(its with Arabic Windows encoding “windows-1256″”)
The following code comparing the DB password and the hashed password they should match:
//”y)@” is the salt

string password = “كودلاب”;
foreach (EncodingInfo enc1 in Encoding.GetEncodings())
foreach (EncodingInfo enc2 in Encoding.GetEncodings())
//foreach (EncodingInfo enc3 in list3)
if (Md5Hash(Md5Hash(password, enc1.GetEncoding()) + “y)@”, enc2.GetEncoding()) == “acfae8024d61fe3697203fbf0fc6e6ed”)
MessageBox.Show(enc1.Name + ” – ” + enc2.Name);

Can anybody help

Add a comment





OKCOOL Wordpress theme created by OKCOOL