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.

Comments
victorantos
said on 24 April 2008That’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 2008The 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 2008Hidden 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 2008This 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 2008I’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 2008Thanks 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 2008I 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