什么是ASP.NET会员使用的默认哈希algorithm?

什么是ASP.NET会员使用的默认哈希algorithm? 我该如何改变它?

编辑:不要原样使用会员供应商,因为在保护用户密码方面,这是非常不足的

鉴于使用“会员提供商散列algorithm”的search结果将这个答案作为第一个结果以及将会推断的福音的事实,我应该警告人们使用这样的成员提供程序并使用SHA-1之类的散列,MD5等混淆数据库中的密码。

TL;博士

使用像bcrypt,scrypt或(如果您需要符合FIPS)的密钥派生函数,PBKDF2的工作因子足以使单个密码的哈希时间接近1000ms或更长。

现在的Hashes很容易被暴力破解,最近有很多关于数据泄露的例子。 为了防止用户的密码在下一次黑客中以pastebin结尾,请确保密码被散列,并且函数需要足够长的时间来计算!

而不是会员提供商,试试IdentityReboot或Troy Hunt至less谈到的来自微软的更新实现 。

同样有趣的是,在上面提到的相同的google结果中,我发现一个教程向人们展示了使用JtR或Hashcat等stream行工具蛮力强制这些密码哈希值的方法。 在一个定制的GPU平台上,SHA1可以以每秒 48867 万次哈希的惊人速度破解! 有了像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); } 

如果你想知道更多关于如何改变它,我仍然需要找出(除非使用自定义提供程序见下文),但SHA-1现在是相当不错的。 如果你想扭转或查找这些人做了一些工作: http : //forums.asp.net/p/1336657/2899172.aspx

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

如果您正在制作自定义提供程序,则可以创build散列和encryptionalgorithm和方法。

 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; } 

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

默认的哈希algorithmtypes是SHA1。 有两种方法可以改变这一点。

1)如果您正在使用IIS 7,则可以使用“机器密钥”configuration(如下所示)更新它。 这使您可以从可用选项列表中selectencryption方法,并指定密钥或密钥生成选项。

机器从IIS 7管理工具的关键配置页面

2)如果您正在使用IIS 6,则可以使用web.config文件中的membership元素更改散列algorithmtypes:

 <membership defaultProvider="provider name" userIsOnlineTimeWindow="number of minutes" hashAlgorithmType="SHA1"> <providers>...</providers> </membership> 

根据文档, hashAlgorithmType属性的string值可以是任何提供的.Net散列algorithmtypes。 有点挖掘显示ASP.Net 2,3和3.5的有效值是MD5RIPEMD160SHA1SHA256SHA384SHA512 。 这里的重要部分是所有这些类都从HashAlgorithminheritance。

hashAlgorithmType属性的值也可以是machine.config文件中的cryptoNameMapping元素的条目。 如果你需要第三方散列algorithm,你可以使用它。 如果您使用ASP.Net 2或更高版本,machine.config文件通常可以在C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG 。 你可以阅读更多关于在这里设置这些值。

默认的哈希algorithm在.NET 4.0 Framework中改为HMACSHA256。

请注意,与SHA-1不同,HMAC SHA-256是一个密钥散列。 如果你的哈希行为是非确定性的,你可能没有设置一个键,强制它使用一个随机的键。 类似于以下内容的是罪魁祸首(这正是我花了一个小时计算出来的:p)。

 HashAlgorithm.Create(Membership.HashAlgorithmType) 

如果您希望使用现有提供程序,则可以使用本指南将其还原为以前的默认设置。

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

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

 public string EncodePassword(string pass, string salt) { byte[] bytes = Encoding.Unicode.GetBytes(pass); 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); } 

哈希algorithm有一个修正,你必须使用:

 byte[] src = Convert.FromBase64String(salt); 

代替

 byte[] src = Encoding.Unicode.GetBytes(salt); 

阅读文章http://svakodnevnica.com.ba/index.php?option=com_kunena&func=view&catid=4&id=4&Itemid=5&lang=en#6

我附上一个代码片段,显示在上面的Rawbert的答案F#

 open System open System.Security.Cryptography open System.Text module PasswordHelper = let EncodePassword(pass : string, salt : string) = let bytes = Encoding.Unicode.GetBytes(pass) let src = Convert.FromBase64String(salt) let dst : byte array = Array.zeroCreate (src.Length + bytes.Length) Buffer.BlockCopy(src, 0, dst, 0, src.Length) Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length) let algorithm = HashAlgorithm.Create("SHA1") let inArray = algorithm.ComputeHash(dst) Convert.ToBase64String(inArray) 

这是来自活动应用程序的工作代码