放弃replaceFormsAuthentication.HashPasswordForStoringInConfigFile?

升级到.Net 4.5后,我现在得到“System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile已过时”的警告,build议使用成员API。

对于新项目来说,这一切都非常好,但是在这个阶段(用户数据和散列密码已经存在),我不能很好地改变成一个自定义的成员资格提供者,可能会有不同的散列方式。

这个问题的推荐方式是什么? 继续使用“过时的”调用显然不是build议的path,那么它被“仅使用成员API”之外的东西所取代?

这是SHA1变体的解决scheme。

  public static string GetSwcSHA1(string value) { SHA1 algorithm = SHA1.Create(); byte[] data = algorithm.ComputeHash(Encoding.UTF8.GetBytes(value)); string sh1 = ""; for (int i = 0; i < data.Length; i++) { sh1 += data[i].ToString("x2").ToUpperInvariant(); } return sh1; } 

对于MD5,您只需将algorithm更改为:

 MD5 algorithm = MD5.Create(); 

希望你不要介意,只要在上面添加你的代码的VB.NET变体:

  Public Shared Function CreateHash(saltAndPassword) As String Dim Algorithm As SHA1 = SHA1.Create() Dim Data As Byte() = Algorithm.ComputeHash(Encoding.UTF8.GetBytes(saltAndPassword)) Dim Hashed As String = "" For i As Integer = 0 To Data.Length - 1 Hashed &= Data(i).ToString("x2").ToUpperInvariant() Next Return Hashed End Function 

这个问题的推荐方式是什么? 继续使用“过时的”调用显然不是build议的path,那么它被“仅使用成员API”之外的东西所取代?

纯粹在.NET Framework中,最好的办法就是把所有的东西都改成PBKDF2,Bcrypt或者Scrypt。 PBKDF2在.NET中由Rfc2898DeriveBytes类提供 。

第二个最好的方法是结束两个“版本”的密码:

  • 版本0本来就是旧的HashPasswordForStoringInConfigFile,但你可以批量更新,离线更新到版本1,并且在任何人窃取他们之前删除那些旧的哈希值,并且在贸易新闻中最终得到可悲的90年代密码哈希值。
  • 版本1,它是现有HashPasswordForStoringInConfigFile值的PBKDF2! 也就是说,你把目前令人讨厌的旧哈希值,和PBKDF2他们用一个新的随机盐和大量的迭代,并存储结果。 然后,当用户想要login时,将密码提供给@RichardBažant编写的代码,以便您拥有HashPasswordForStoringInConfigFile将返回的内容, 然后将PBKDF2应用于该结果!
    • 即它实际上是Rfc2898DeriveBytes(HashPasswordForStoringInConfigFile(密码)),PerUserSalt,YourIterations)
  • 版本2,具有版本1哈希的用户升级到。 除了“版本”以外的所有列都是相同的,但是在计算和validation版本1之后,计算Rfc2898DeriveBytes(password),PerUserSalt,YourIterations)并将版本1散列replace为版本2散列(并将版本更改为2,当然)。

第三个最好的方法是第二个最好的方法,但只有版本1.要小心,这种方式是DCC2的疯狂 – 你不断包装你的旧输出在新的algorithm

在这两种情况下,您都会将PBKDF2-HMAC-SHA-1结果存储在数据库中,因此您需要:

  • 密码哈希(二进制(20)) – 即PBKDF2输出。
  • 你的salt(二进制(16),由RNGCryptoServiceProvider类每个用户生成)
  • 可选:PBKDF2迭代的次数(INT,从数以万计开始,直到服务器将在最大负载下处于CPU绑定之前;随着您的硬件升级而增加)
    • 这允许您每次用户input他们的(正确的)密码时透明地提高您的安全级别。通过首先validation它的正确性,然后用更高的迭代次数对其进行重新哈希
  • 可选:“版本”(TINYINT),以便稍后升级到其他algorithm更容易,因为您可以同时拥有多个版本。

PS版本1或版本2更新的algorithm,Jither创build了一个.NET库,能够使用PBKDF2-HMAC-SHA256,PBKDF2-HMAC-SHA512等; 我的Github存储库包含一个合适的testing向量组的变体。

理查德的回答对我很好。 这是从.NET Framework 4.5反编译的代码。 如果任何事情是最好的,请使用它。 我想这可能会快一点。

  public static string BinaryToHex(byte[] data) { if (data == null) { return null; } char[] hex = new char[checked((int)data.Length * 2)]; for (int i = 0; i < (int)data.Length; i++) { byte num = data[i]; hex[2 * i] = NibbleToHex((byte)(num >> 4)); hex[2 * i + 1] = NibbleToHex((byte)(num & 15)); } return new string(hex); } private static char NibbleToHex(byte nibble) { int aChar = (nibble < 10 ? nibble + 48 : nibble - 10 + 65); return (char)aChar; } 

为什么不能使用.Net最简单的一个

 public static string HashString(string inputString, string hashName) { var algorithm = HashAlgorithm.Create(hashName); if (algorithm == null) throw new ArgumentException("Unrecognized hash name", hashName); byte[] hash = algorithm.ComputeHash(Encoding.UTF8.GetBytes(inputString)); return Convert.ToBase64String(hash); }