我正在尝试为密码实施自定义商店。在更改密码之前,我需要先检查密码是否已被使用最后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>
答案 0 :(得分:3)
成员资格提供程序使用以下算法来哈希密码。
默认哈希值将根据成员资格提供程序的版本而有所不同。
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;
}
默认哈希算法是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);
}