我正在迁移我的旧 ASP.NET Webforms 应用程序以开始使用 ASP.NET 内置 DefaultMembershipProvider。我的旧自制身份验证模块用于存储密码的 SHA256 哈希值。我认为“升级”到 DefaultMembershipProvider,它也在 SQL DB 中存储散列,这意味着我也可以迁移这些散列,因此为当前用户提供无痛升级(这样他们就不必重置密码)。
现在,这并没有按计划工作(显然!),我开始研究 DefaultMembershipProvider 的来源(更具体地说,就在这里:https ://github.com/wyxy2005/bluceNet/tree/master/ System.Web.Providers),我遇到了以下功能:
private string EncodePassword(string pass, int passwordFormat, string salt)
{
if (passwordFormat == 0)
{
return pass;
}
byte[] bytes = Encoding.Unicode.GetBytes(pass);
byte[] src = Convert.FromBase64String(salt);
byte[] inArray = null;
if (passwordFormat == 1)
{
HashAlgorithm hashAlgorithm = this.GetHashAlgorithm();
KeyedHashAlgorithm algorithm2 = hashAlgorithm as KeyedHashAlgorithm;
if (algorithm2 != null)
{
if (algorithm2.Key.Length == src.Length)
{
algorithm2.Key = src;
}
else if (algorithm2.Key.Length < src.Length)
{
byte[] dst = new byte[algorithm2.Key.Length];
Buffer.BlockCopy(src, 0, dst, 0, dst.Length);
algorithm2.Key = dst;
}
else
{
int num2;
byte[] buffer5 = new byte[algorithm2.Key.Length];
for (int i = 0; i < buffer5.Length; i += num2)
{
num2 = Math.Min(src.Length, buffer5.Length - i);
Buffer.BlockCopy(src, 0, buffer5, i, num2);
}
algorithm2.Key = buffer5;
}
inArray = algorithm2.ComputeHash(bytes);
}
else
{
byte[] buffer6 = new byte[src.Length + bytes.Length];
Buffer.BlockCopy(src, 0, buffer6, 0, src.Length);
Buffer.BlockCopy(bytes, 0, buffer6, src.Length, bytes.Length);
inArray = hashAlgorithm.ComputeHash(buffer6);
}
}
else
{
byte[] buffer7 = new byte[src.Length + bytes.Length];
Buffer.BlockCopy(src, 0, buffer7, 0, src.Length);
Buffer.BlockCopy(bytes, 0, buffer7, src.Length, bytes.Length);
inArray = this.EncryptPassword(buffer7, this.LegacyPasswordCompatibilityMode);
}
return Convert.ToBase64String(inArray);
}
现在,在我的特定场景中,我没有任何密码盐,因为我的旧身份验证模块没有使用它,所以它string salt
是空的,就像byte [] src
. 默认使用的散列算法是 HMACSHA256,它是一个键控散列函数。所以我们进入这个for
始终num2
为0的循环。由于num2
也用作增量器,我们进入一个无限循环。
算法不应该针对这种特定条件进行测试吗?这不应该是一个简单的错误,只需对代码进行单元测试就可以捕获吗?还是我忽略了什么?