I am in a project where I need to create a MD5 login that works like the PHP MD5 function. I have set this up and it seems to work but the results are not coming out the same. What I mean is the same login using the "PHP MD5" hashed password does not match the .NET hashed password. Both are taking a salt and the password and then creating the hash but the results are different for the same entered password.
Simple PHP CODE:
Code: Select all
function encryptString($string) {
return md5($string . PASSWORD_SALT);
}
$string is what is entered in the password field.
.NET CODE:
[csharp] protected void Login_Click(object sender, EventArgs e) { string SaltValue = "thesalt"; //Salt value string HashAlgorithm = "MD5"; //MD5 string PasswordtoHash = "hello123"; //Password typed in password textbox // Convert SaltValue string to a UTF-8 encoded byte[] - PHP MD5 encodes in a different way? byte[] SaltValueBytes = Encoding.UTF8.GetBytes(SaltValue); Session["HashedPassword"] = ComputeHash(PasswordtoHash, HashAlgorithm, SaltValueBytes); complete(); } /// <summary> /// Generates a hash for the given plain text value and returns a /// base64-encoded result. This salt is stored at /// the end of the hash value, so it can be used later for hash /// verification. /// </summary> /// <param name="plainText"> /// Plaintext value to be hashed. The function does not check whether /// this parameter is null. /// </param> /// <param name="hashAlgorithm"> /// Name of the hash algorithm. Allowed values are: "MD5", "SHA1", /// "SHA256", "SHA384", and "SHA512" (if any other value is specified /// MD5 hashing algorithm will be used). This value is case-insensitive. /// </param> /// <param name="saltBytes"> /// Salt bytes. This parameter can be null, in which case a random salt /// value will be generated. /// </param> /// <returns> /// Hash value formatted as a base64-encoded string. /// </returns> public static string ComputeHash(string plainText, string hashAlgorithm, byte[] saltBytes) { // Convert plain text into a byte array. Once again UTF8, is this the same encoding as PHP MD5? byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText); // Allocate array, which will hold plain text and salt. byte[] plainTextWithSaltBytes = new byte[plainTextBytes.Length + saltBytes.Length]; // Copy plain text bytes into resulting array. for (int i = 0; i < plainTextBytes.Length; i++) plainTextWithSaltBytes = plainTextBytes; // Append salt bytes to the resulting array. for (int i = 0; i < saltBytes.Length; i++) plainTextWithSaltBytes[plainTextBytes.Length + i] = saltBytes; // Because we support multiple hashing algorithms, we must define // hash object as a common (abstract) base class. We will specify the // actual hashing algorithm class later during object creation. HashAlgorithm hash; // Make sure hashing algorithm name is specified. if (hashAlgorithm == null) hashAlgorithm = ""; // Initialize appropriate hashing algorithm class. switch (hashAlgorithm.ToUpper()) { case "SHA1": hash = new SHA1Managed(); break; case "SHA256": hash = new SHA256Managed(); break; case "SHA384": hash = new SHA384Managed(); break; case "SHA512": hash = new SHA512Managed(); break; default: hash = new MD5CryptoServiceProvider(); break; } // Compute hash value of our plain text with appended salt. byte[] hashBytes = hash.ComputeHash(plainTextWithSaltBytes); // Create array which will hold hash and original salt bytes. byte[] hashWithSaltBytes = new byte[hashBytes.Length + saltBytes.Length]; // Copy hash bytes into resulting array. for (int i = 0; i < hashBytes.Length; i++) hashWithSaltBytes = hashBytes; // Append salt bytes to the result. for (int i = 0; i < saltBytes.Length; i++) hashWithSaltBytes[hashBytes.Length + i] = saltBytes; // Convert result into a base64-encoded string. string hashValue = Convert.ToBase64String(hashWithSaltBytes); // Return the result. return hashValue; } [/csharp]
THE RESULTS:
XXXXXXXX TEXT VALUES TYPED IN FORM XXXXXXXX
Username typed in form = : example
Password typed in form = : hello123
XXXXXXXX SALT VALUE XXXXXXXX
Salt = : thesalt
XXXXXXXX PHP MD5 VALUES XXXXXXXX
Results after MD5 and salt are hashed via PHP
"5b1980b160ae19131ae1a68c76685d1b"
XXXXXXXX .NET MD5 VALUES XXXXXXXX
Results after MD5 and salt are hashed via .NET C#:
"WxmAsWCuGRMa4aaMdmhdG0EyZGluZ00yU0dTYWwydG9QYTJzd29yZHNNYWtlc29uZXdheUVuY3J5cHRlZEhhc2hlc01vcmVTZWN1cmU="
As you can see the password and salt are identical but the results do not match. The .NET result is about 3 times longer than the PHP result. I am not sure why this is happening.
I also read this post dated April 2008 that in order to get .NET to match an MD5 with the PHP md5 function you need to use a UTF7 encoding.
See http://ok-cool.com/posts/read/125-php-m ... s-net-md5/ for more details. Some on that post say UT7 isn't the best way to go and some say it is. Other sites say it has nothing to do with encoding at all; this gets confusing.
I am not sure if this is a encoding issue or not. But the results are way off; not even close.
Any Help or advice is appreciated
Thanks,
Mike