升级到.Net 4.5后,我现在收到“System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile已过时”的警告,建议改为使用成员资格API。
这对新项目来说非常好,但是在这个阶段(存在用户数据和散列密码),我不能很好地改变为具有可能不同的散列方式的自定义成员资格提供者。
对于像这样的问题,推荐的方法是什么?继续使用“过时”调用显然不是建议的路径,所以除了“只使用成员资格API”之外,它是否被其他东西取代?
答案 0 :(得分:49)
这是SHA1变体的解决方案。
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,您只需将算法更改为:
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
答案 1 :(得分:9)
对于像这样的问题,推荐的方法是什么?继续使用“过时”调用显然不是建议的路径,所以除了“只使用成员资格API”之外,它是否被其他东西取代?
纯粹在.NET Framework中最好的方法(你已经排除了)是改变所有内容,以便通过PBKDF2,Bcrypt或Scrypt对密码进行哈希处理。 PBKDF2由.NET Rfc2898DeriveBytes Class提供。
第二种最好的方法是使用两个“版本”的密码:
第三种最好的方法是第二种最好的方法,但只有版本1.请注意,这种方式是DCC2疯狂 - 你继续将旧输出包装在更新的算法中
在这两种情况下,您都将PBKDF2-HMAC-SHA-1结果存储在数据库中,因此您需要:
P.S。对于版本1或版本2的新算法,Jither创建了一个支持PBKDF2-HMAC-SHA256,PBKDF2-HMAC-SHA512等的.NET库; my Github repository包含一个带有一组合理测试向量的变体。
答案 2 :(得分:2)
理查德的回答对我很有帮助。 这是从.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;
}
答案 3 :(得分:2)
为什么不能使用最简单的.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);
}