Yuri Morales
Yuri Morales

Reputation: 2518

MD5CryptoServiceProvider in ASP.NET Core

I have a database with passwords created in the old Identity system. Passwords were hashed using the MD5CryptoServiceProvider class. I now need to use these passwords in ASP.NET MVC Core but MD5CryptoServiceProvider doesn't exist.

In .NET Framework the function I used to compute the hashes is:

public static string CreateHash(string unHashed)
{
    var x = new System.Security.Cryptography.MD5CryptoServiceProvider();
    var data = Encoding.ASCII.GetBytes(unHashed);
    data = x.ComputeHash(data);
    return Encoding.ASCII.GetString(data);
}

I've tried the following two functions in ASP.NET Core:

public static string CreateHash(string unHashed)
{
    var x = new System.Security.Cryptography.HMACMD5();
    var data = Encoding.ASCII.GetBytes(unHashed);
    data = x.ComputeHash(data);
    return Encoding.ASCII.GetString(data);
}

and

public static string MD5Hash(string input)
{
    using (var md5 = MD5.Create())
    {
        var result = md5.ComputeHash(Encoding.ASCII.GetBytes(input));
        var strResult = BitConverter.ToString(result);
        return strResult.Replace("-", "");
    }
}

Neither method returns the same string that MD5CryptoServiceProvider class does in the first method. I can't change the entire database to use new passwords.

Any fix to this?

Upvotes: 12

Views: 22981

Answers (2)

ADM-IT
ADM-IT

Reputation: 4200

Here is my version of md5 helper

public static string ToMD5Hash(this string str)
{
    if (string.IsNullOrEmpty(str))
        return null;

    return Encoding.ASCII.GetBytes(str).ToMD5Hash();
}

public static string ToMD5Hash(this byte[] bytes)
{
    if (bytes == null || bytes.Length == 0)
        return null;

    using (var md5 = MD5.Create())
    {
        return string.Join("", md5.ComputeHash(bytes).Select(x => x.ToString("X2")));
    }
}

Please note that MD5 is obsolete and not safe. Please use different hash functions in your future projects (see How to hash a password).

Upvotes: 5

Brett Wolfington
Brett Wolfington

Reputation: 6627

There are two issues here:

First, you are using different methods to convert the byte array back into a string. In your first and second methods, you use

return Encoding.ASCII.GetString(data);

In your third method, you use:

var strResult = BitConverter.ToString(result);
return strResult.Replace("-", "");

These do not output the same results.

Second, while the hash functions used in the first and third examples are indeed identical, the method used in the second example is not.

In short, to get what you want, use the third option, but use the same method to convert it back into a string that you used in the first example (if that is what you had previously been using):

public static string MD5Hash(string input)
{
    using (var md5 = MD5.Create())
    {
        var result = md5.ComputeHash(Encoding.ASCII.GetBytes(input));
        return Encoding.ASCII.GetString(result);
    }
}

Upvotes: 24

Related Questions