Asp.net会员使用什么哈希算法?

时间:2016-04-29 19:13:34

标签: c# asp.net algorithm hash membership-provider

我正在尝试为密码实施自定义商店。在更改密码之前,我需要先检查密码是否已被使用最后8次用户更改了密码。

var hashingAlgorithm = ConfigurationManager.AppSettings("MembershipProviderHashAlgorithm");
var hashedPasswordDetails = pwdHistory.GetRecentPasswordDetails(userName);
foreach (var passwordDetails_loopVariable in hashedPasswordDetails) 
{
  passwordDetails = passwordDetails_loopVariable;
  var encodedPassword = pwdEncr
            .EncodePassword(proposedNewPassword, passwordDetails.Salt, hashingAlgorithm);
  var hashedPassword = passwordDetails.HashedPassword;
  if (hashedPassword.Equals(encodedPassword)) //This line always return FALSE.
  {
     return true;               
  }
}
return false;

我遇到的问题是从表中返回的密码总是与我输入的密码不同(事件清楚时有相同的情况)。那是因为哈希算法

我尝试过SHA和SHA1而没有运气。是否存在ASP.NEt成员资格使用的特定散列算法?我正在使用 System.Web.Security.SqlMembershipProvider版本4.0.0.0

<add key="MembershipProviderHashAlgorithm" value="SHA" />

感谢您的帮助。

修改

以下是 web.config 中会员资格部分的配置部分。有没有办法告诉使用哪种算法。

<membership defaultProvider="SqlProvider" userIsOnlineTimeWindow="15">
  <providers>
    <clear />
    <add name="SqlProvider" type="System.Web.Security.SqlMembershipProvider,                  
         System.Web, Version=4.0.0.0, Culture=neutral,                  
         PublicKeyToken=b03f5f7f11d50a3a"
         connectionStringName="myConnectionString"
         ../..
         requiresUniqueEmail="false"
         passwordFormat="Hashed"
         maxInvalidPasswordAttempts="5"
         minRequiredPasswordLength="7"
         passwordAttemptWindow="10"/>
  </providers>
</membership>

1 个答案:

答案 0 :(得分:3)

成员资格提供程序使用以下算法来哈希密码。

默认哈希值将根据成员资格提供程序的版本而有所不同。

ASP.Net Universal Provider

MVC 4 and ASP.NET 4 and 4.5默认哈希为 SHA256 (HMACSHA256)

public string EncodePassword(string pass, 
    MembershipPasswordFormat passwordFormat, string salt)
{
    byte[] numArray;
    byte[] numArray1;
    string base64String;

    if (passwordFormat == MembershipPasswordFormat.Hashed)
    {
        byte[] bytes = Encoding.Unicode.GetBytes(pass);
        byte[] numArray2 = Convert.FromBase64String(salt);
        byte[] numArray3;

        // Hash password
        HashAlgorithm hashAlgorithm = HashAlgorithm.Create(Membership.HashAlgorithmType);

        if (hashAlgorithm as KeyedHashAlgorithm == null)
        {
            numArray1 = new byte[numArray2.Length + bytes.Length];
            Buffer.BlockCopy(numArray2, 0, numArray1, 0, numArray2.Length);
            Buffer.BlockCopy(bytes, 0, numArray1, numArray2.Length, bytes.Length);
            numArray3 = hashAlgorithm.ComputeHash(numArray1);
        }
        else
        {
            KeyedHashAlgorithm keyedHashAlgorithm = (KeyedHashAlgorithm)hashAlgorithm;

            if (keyedHashAlgorithm.Key.Length != numArray2.Length)
            {

                if (keyedHashAlgorithm.Key.Length >= numArray2.Length)
                {
                    numArray = new byte[keyedHashAlgorithm.Key.Length];
                    int num = 0;
                    while (true)
                    {
                        if (!(num < numArray.Length))
                        {
                            break;
                        }
                        int num1 = Math.Min(numArray2.Length, numArray.Length - num);
                        Buffer.BlockCopy(numArray2, 0, numArray, num, num1);
                        num = num + num1;
                    }
                    keyedHashAlgorithm.Key = numArray;
                }
                else
                {
                    numArray = new byte[keyedHashAlgorithm.Key.Length];
                    Buffer.BlockCopy(numArray2, 0, numArray, 0, numArray.Length);
                    keyedHashAlgorithm.Key = numArray;
                }
            }
            else
            {
                keyedHashAlgorithm.Key = numArray2;
            }
            numArray3 = keyedHashAlgorithm.ComputeHash(bytes);
        }

        base64String = Convert.ToBase64String(numArray3);
    }
    else if (passwordFormat == MembershipPasswordFormat.Encrypted)
    {
        throw new NotImplementedException("Encrypted password method is not supported.");
    }
    else
    {
        base64String = pass;
    }

    return base64String;
}

旧的ASP.Net会员提供商

默认哈希算法是SHA-1。

private string EncodePassword(string pass, int passwordFormat, string salt)
{ 
    if (passwordFormat == 0) // MembershipPasswordFormat.Clear
        return pass;

    byte[] bIn = Encoding.Unicode.GetBytes(pass); 
    byte[] bSalt = Convert.FromBase64String(salt);
    byte[] bRet = null; 

    if (passwordFormat == 1)
    { // MembershipPasswordFormat.Hashed 
        HashAlgorithm hm = GetHashAlgorithm();
        if (hm is KeyedHashAlgorithm) {
            KeyedHashAlgorithm kha = (KeyedHashAlgorithm) hm;
            if (kha.Key.Length == bSalt.Length) { 
                kha.Key = bSalt;
            } else if (kha.Key.Length < bSalt.Length) { 
                byte[] bKey = new byte[kha.Key.Length]; 
                Buffer.BlockCopy(bSalt, 0, bKey, 0, bKey.Length);
                kha.Key = bKey; 
            } else {
                byte[] bKey = new byte[kha.Key.Length];
                for (int iter = 0; iter < bKey.Length; ) {
                    int len = Math.Min(bSalt.Length, bKey.Length - iter); 
                    Buffer.BlockCopy(bSalt, 0, bKey, iter, len);
                    iter += len; 
                } 
                kha.Key = bKey;
            } 
            bRet = kha.ComputeHash(bIn);
        }
        else {
            byte[] bAll = new byte[bSalt.Length + bIn.Length]; 
            Buffer.BlockCopy(bSalt, 0, bAll, 0, bSalt.Length);
            Buffer.BlockCopy(bIn, 0, bAll, bSalt.Length, bIn.Length); 
            bRet = hm.ComputeHash(bAll); 
        }
    } else { 
        byte[] bAll = new byte[bSalt.Length + bIn.Length];
        Buffer.BlockCopy(bSalt, 0, bAll, 0, bSalt.Length);
        Buffer.BlockCopy(bIn, 0, bAll, bSalt.Length, bIn.Length);
        bRet = EncryptPassword(bAll, _LegacyPasswordCompatibilityMode); 
    }

    return Convert.ToBase64String(bRet); 
}