ASP.NET成员资格使用的默认哈希算法是什么?

ibu*_*kov 54 membership asp.net authentication hash

ASP.NET成员资格使用的默认哈希算法是什么?我怎么能改变它?

Rya*_*sen 47

编辑:不要按原样使用成员资格提供程序,因为它在保护用户密码方面严重不足

鉴于谷歌搜索"会员提供程序哈希算法"这个答案作为第一个结果,以及将被推断的福音,我应该警告人们使用像这样的成员资格提供者并使用像SHA-1这样的哈希,MD5等来模糊数据库中的密码.

TL;博士

使用密钥派生函数,如bcrypt,scrypt或(如果需要FIPS兼容性)PBKDF2,其工作因子足以使单个密码的散列时间必须接近1000毫秒或更长.

在最近的历史中,有大量数据泄露的例子,现在哈希很容易暴力破解.为了防止用户的密码在下一次黑客攻击中结束使用,请确保使用需要足够长时间计算的函数对密码进行哈希处理!

而不是成员资格提供程序,尝试IdentityReboot或者特洛伊亨特至少谈到的Microsoft新实现.

同样有趣的是,在上面提到的相同谷歌搜索结果中,我找到一个教程,显示人们使用流行的工具(如JtR或Hashcat )来强制使用这些密码哈希是多么容易.在自定义GPU平台上,SHA1可以以惊人的速度破解,每秒 4886.7 万个哈希!使用像rockyou之类的免费字典,拥有数据库的有动力的人很快就会拥有大部分用户密码.作为开发人员,做出保护用户密码安全所必需的道德责任是您的道德责任.


默认散列是SHA1,但是它们也是盐,它是base64:

public string EncodePassword(string pass, string salt)
{
    byte[] bytes = Encoding.Unicode.GetBytes(pass);
    byte[] src = Encoding.Unicode.GetBytes(salt);
    byte[] dst = new byte[src.Length + bytes.Length];
    Buffer.BlockCopy(src, 0, dst, 0, src.Length);
    Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length);
    HashAlgorithm algorithm = HashAlgorithm.Create("SHA1");
    byte[] inArray = algorithm.ComputeHash(dst);
    return Convert.ToBase64String(inArray);
}
Run Code Online (Sandbox Code Playgroud)

如果你想了解更多关于如何更改它的信息,我仍然需要了解(除非使用自定义提供程序,请参见下文)但是SHA-1现在非常好用.如果你想要反转它或从中查找这些人做了一些工作:http://forums.asp.net/p/1336657/2899172.aspx

如果可能需要,这个SO问题将有助于扭转或复制这种技术. 在Ruby中重新实现ASP.NET成员资格和用户密码哈希

如果您要创建自定义提供程序,则可以创建哈希和加密算法和方法.

private byte[] ConvertPasswordForStorage(string Password)
      {
         System.Text.UnicodeEncoding ue = 
      new System.Text.UnicodeEncoding();
         byte[] uePassword = ue.GetBytes(Password);
         byte[] RetVal = null;
         switch (_PasswordFormat)
         {
            case MembershipPasswordFormat.Clear:
               RetVal = uePassword;
               break;
            case MembershipPasswordFormat.Hashed:

               HMACSHA1 SHA1KeyedHasher = new HMACSHA1();
               SHA1KeyedHasher.Key = _ValidationKey;
               RetVal = SHA1KeyedHasher.ComputeHash(uePassword);
               break;
            case MembershipPasswordFormat.Encrypted:
               TripleDESCryptoServiceProvider tripleDes = new 
       TripleDESCryptoServiceProvider();
               tripleDes.Key = _DecryptionKey;
               tripleDes.IV = new byte[8];
               MemoryStream mStreamEnc = new MemoryStream();
               CryptoStream cryptoStream = new CryptoStream(mStreamEnc, 
        tripleDes.CreateEncryptor(), 
      CryptoStreamMode.Write);

               cryptoStream.Write(uePassword, 0, uePassword.Length);
               cryptoStream.FlushFinalBlock();
               RetVal = mStreamEnc.ToArray();
               cryptoStream.Close();
               break;

         }
         return RetVal;
      }

private string GetHumanReadablePassword(byte[] StoredPassword)
      {
         System.Text.UnicodeEncoding ue = new System.Text.UnicodeEncoding();
         string RetVal = null;
         switch (_PasswordFormat)
         {
            case MembershipPasswordFormat.Clear:
               RetVal = ue.GetString(StoredPassword);
               break;
            case MembershipPasswordFormat.Hashed:
               throw new ApplicationException(
        "Password cannot be recovered from a hashed format");

            case MembershipPasswordFormat.Encrypted:
               TripleDESCryptoServiceProvider tripleDes = 
        new TripleDESCryptoServiceProvider();
               tripleDes.Key = _DecryptionKey;
               tripleDes.IV = new byte[8];
               CryptoStream cryptoStream = 
        new CryptoStream(new MemoryStream(StoredPassword), 
      tripleDes.CreateDecryptor(), CryptoStreamMode.Read);
               MemoryStream msPasswordDec = new MemoryStream();
               int BytesRead = 0;
               byte[] Buffer = new byte[32];
               while ((BytesRead = cryptoStream.Read(Buffer, 0, 32)) > 0)
               {
                  msPasswordDec.Write(Buffer, 0, BytesRead);

               }
               cryptoStream.Close();

               RetVal = ue.GetString(msPasswordDec.ToArray());
               msPasswordDec.Close();
               break;
         }
         return RetVal;
      }
Run Code Online (Sandbox Code Playgroud)

http://msdn.microsoft.com/en-us/library/aa479048.aspx

  • 这里的EncodePassword功能不起作用.请参阅下面的"Rawbert"中的工作示例. (4认同)
  • 可能更简单地说这是2009年解决问题时的解决方案,而不是像我现在希望知道的大多数开发人员那样的冗长反应.我相信大多数好的开发人员都会检查解决方案的日期,如果在今天仍在运行不足的散列系统上工作,可能只会使用它.在2009年,SHA-1"现在非常好","现在"已经过去了. (3认同)

小智 32

Ryan Christensen上述答案并不完整.它将salt转换为byte []的部分不正确.

这是我在客户端解决方案中实现的一个工作示例:

public string Hash(string value, string salt)
    {
        byte[] bytes = Encoding.Unicode.GetBytes(value);
        byte[] src = Convert.FromBase64String(salt);
        byte[] dst = new byte[src.Length + bytes.Length];
        Buffer.BlockCopy(src, 0, dst, 0, src.Length);
        Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length);
        HashAlgorithm algorithm = HashAlgorithm.Create("SHA1");
        byte[] inArray = algorithm.ComputeHash(dst);
        return Convert.ToBase64String(inArray);
    }
Run Code Online (Sandbox Code Playgroud)

  • 幸运的是,只有salt的读取与Ryan的实现不同。这意味着,如果您有一组由错误实现生成的密码+盐,并且您想开始使用标准成员资格提供程序(或至少此处给出的正确实现),则只需修复数据库中的所有现有盐: `var fixedSalt = Convert.ToBase64String(Encoding.Unicode.GetBytes(oldSalt);` (2认同)

Mik*_*keD 27

默认的哈希算法类型是SHA1.有两种方法可以改变它.

1)如果您使用的是IIS 7,则可以使用"机器密钥"配置对其进行更新(如下所示).这允许您从可用选项列表中选择加密方法,并指定键或密钥生成选项.

IIS 7管理工具中的计算机密钥配置页面

2)如果您使用的是IIS 6,则可以使用web.config文件中的membership元素更改哈希算法类型:

<membership
    defaultProvider="provider name"
    userIsOnlineTimeWindow="number of minutes"
    hashAlgorithmType="SHA1">
    <providers>...</providers>
</membership>
Run Code Online (Sandbox Code Playgroud)

根据文档,hashAlgorithmType属性的字符串值可以是任何提供的.Net散列算法类型.挖掘的比特表明,对于ASP.Net 2,3和3.5的有效值是MD5,RIPEMD160,SHA1,SHA256,SHA384,SHA512.这里重要的部分是所有这些类都继承自HashAlgorithm.

hashAlgorithmType属性的值也可以是machine.config文件中cryptoNameMapping元素的条目.如果您需要第三方哈希算法,则可以使用此方法.C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG如果您使用的是ASP.Net 2或更高版本,通常可以找到machine.config文件.您可以在此处详细了解如何设置这些值.

  • 可悲的是,Bcrypt在这些名单中并不存在. (3认同)
  • @Joel ASP.Net是可扩展的,所以你可以选择这个实现(http://derekslager.com/blog/posts/2007/10/bcrypt-dotnet-strong-password-hashing-for-dotnet-and-mono. ashx)并将其作为自定义HashAlgorithm或通过创建自定义提供程序公开,如另一个答案中所述. (2认同)

phl*_*opy 26

默认哈希算法在.NET 4.0 Framework中更改为HMACSHA256.

请注意,与SHA-1不同,HMAC SHA-256是一个键控哈希.如果您的哈希行为不确定,您可能没有设置密钥,强制它使用随机密钥.类似于以下的东西将是罪魁祸首(这是我花了一个小时搞清楚:p).

HashAlgorithm.Create(Membership.HashAlgorithmType)
Run Code Online (Sandbox Code Playgroud)

如果您希望将其与现有提供程序一起使用,则可以使用本指南将其还原为以前的默认值.