Leo
Leo

Reputation: 2203

MD5 password checking always return false?

I have the following codes to check md5 encrypted password against user input password:

            UserDAO userDAO = new UserDAO();

            // encrypt the input password
            MD5 md5 = new MD5CryptoServiceProvider();
            UTF8Encoding encoder = new UTF8Encoding();
            Byte[] encryptedPassword;
            encryptedPassword = md5.ComputeHash(encoder.GetBytes(TxtBoxPassword.Text));

            // get information for this username and begin checking authentication
            DataTable data = userDAO.GetUserInformation(TxtBoxUsername.Text);
            if (data.Rows.Count == 0)
            {
                LblError.Text = "Wrong username!";
                return;
            }
            Byte[] password = (Byte[])data.Rows[0]["Password"];

            if (!Convert.ToBase64String(password).Equals(Convert.ToBase64String(encryptedPassword)))
            {
                LblError.Text = "Wrong password!";
                return;
            }

The problem is I can run this code just fine on my computer (admin/123456 validated correctly) whereas when I publish my website to a server, the check always return "wrong password"? What gives?

Upvotes: 1

Views: 604

Answers (3)

m4tt1mus
m4tt1mus

Reputation: 1641

Not sure why yours isn't working, but when I wrote the SHA512 implementation below I had some issues with the hash. It doesn't output like you would normally see it displayed for humans. For this reason your data type should be binary in the database. Also here is the implementation I use (with the salt changed) that uses SHA512. Using ByteArrayToHexString puts it in a human recognizable format. Then you can use a varchar in the database.

    /// <summary>
    /// Takes a string as input, SHA512 hashes it, and returns the hexadecimal representation of the hash as a string.
    /// </summary>
    /// <param name="toHash">string to be hashed</param>
    /// <returns>hexadecimal representation of the hash as a string</returns>
    private string GetHash(string toHash)
    {
        /* As of this writing, both the –Cng and –CryptoServiceProvider implementation classes are FIPS-certified, 
         * but –Managed classes are not. http://msdn.microsoft.com/en-us/magazine/ee321570.aspx
         */
        // Salt the string
        toHash = "%my" + toHash.Insert(Convert.ToInt16(toHash.Length / 2), "!secret") + ".sauce#";
        SHA512CryptoServiceProvider hasher = new SHA512CryptoServiceProvider();
        byte[] hashBytes = hasher.ComputeHash(Encoding.Unicode.GetBytes(toHash));
        hasher.Clear();
        return ByteArrayToHexString(hashBytes);
    }

    /// <summary>
    /// Takes a byte[] and converts it to its string hexadecimal representation
    /// </summary>
    /// <param name="ba">Array of bytes[] to convert</param>
    /// <returns>string, hexadecimal representation of input byte[]</returns>
    private string ByteArrayToHexString(byte[] ba)
    {
        StringBuilder hex = new StringBuilder(ba.Length * 2);
        foreach (byte b in ba)
            hex.AppendFormat("{0:x2}", b);
        return hex.ToString();
    }

Upvotes: 3

jordanbtucker
jordanbtucker

Reputation: 6078

Was the password in UTF8 before it was hashed and saved to the UserDAO?

Upvotes: 0

cdhowie
cdhowie

Reputation: 169038

Is the byte[] being munged in the db? Can you log the hash when it goes into the db and log it when you fetch it here and see if they are equal?

Also, note that MD5 is considered weak, and you are not salting passwords. If a data breach were to happen this could easily result in compromised accounts. Consider using SHA1 with random salt.

Upvotes: 0

Related Questions