我正在迁移我的旧版ASP.NET webforms应用程序,以便开始使用ASP.NET内置的DefaultMembershipProvider。我的旧homebrewn authenticationmodule用于存储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
也用作增量器,我们进入无限循环。
算法不应该针对这种特殊情况进行测试吗?难道这不是一个容易出错的错误,只需单击UnitTesting代码即可捕获?或者我忽略了什么?
答案 0 :(得分:0)
我不是安全专家,所以我无法回答你的问题。
以下是新ASP.Net Universal Provider使用的EncodePassword方法。
与旧的MembershipProvider略有不同。你可能想尝试一下。
private string EncodePassword(string pass, int passwordFormat, string salt)
{
byte[] numArray;
byte[] numArray1;
string base64String;
bool length = passwordFormat != 0;
if (length)
{
byte[] bytes = Encoding.Unicode.GetBytes(pass);
byte[] numArray2 = Convert.FromBase64String(salt);
byte[] numArray3 = null;
length = passwordFormat != 1;
if (length)
{
numArray1 = new byte[(int)numArray2.Length + (int)bytes.Length];
Buffer.BlockCopy(numArray2, 0, numArray1, 0, (int)numArray2.Length);
Buffer.BlockCopy(bytes, 0, numArray1, (int)numArray2.Length, (int)bytes.Length);
numArray3 = this.EncryptPassword(numArray1);
}
else
{
HashAlgorithm hashAlgorithm = this.GetHashAlgorithm();
length = hashAlgorithm as KeyedHashAlgorithm <= null;
if (length)
{
numArray1 = new byte[(int)numArray2.Length + (int)bytes.Length];
Buffer.BlockCopy(numArray2, 0, numArray1, 0, (int)numArray2.Length);
Buffer.BlockCopy(bytes, 0, numArray1, (int)numArray2.Length, (int)bytes.Length);
numArray3 = hashAlgorithm.ComputeHash(numArray1);
}
else
{
KeyedHashAlgorithm keyedHashAlgorithm = (KeyedHashAlgorithm)hashAlgorithm;
length = (int)keyedHashAlgorithm.Key.Length != (int)numArray2.Length;
if (length)
{
length = (int)keyedHashAlgorithm.Key.Length >= (int)numArray2.Length;
if (length)
{
numArray = new byte[(int)keyedHashAlgorithm.Key.Length];
int num = 0;
while (true)
{
length = num < (int)numArray.Length;
if (!length)
{
break;
}
int num1 = Math.Min((int)numArray2.Length, (int)numArray.Length - num);
Buffer.BlockCopy(numArray2, 0, numArray, num, num1);
num = num + num1;
}
keyedHashAlgorithm.Key = numArray;
}
else
{
numArray = new byte[(int)keyedHashAlgorithm.Key.Length];
Buffer.BlockCopy(numArray2, 0, numArray, 0, (int)numArray.Length);
keyedHashAlgorithm.Key = numArray;
}
}
else
{
keyedHashAlgorithm.Key = numArray2;
}
numArray3 = keyedHashAlgorithm.ComputeHash(bytes);
}
}
base64String = Convert.ToBase64String(numArray3);
}
else
{
base64String = pass;
}
return base64String;
}