我对如何在不“泄露”安全信息的情况下呈现此信息甚至是本文是否要关注它感到困惑。
如果我应该添加有问题的哈希和密码,请在评论中告知我,我将非常乐意在编辑中进行设置。
足以说明我使用ASP.NET Identity创建的用户无法登录。我使用ILSpy来分离PasswordSignIn
方法,并且能够验证具有提供的用户名的用户确实存在,并且该失败似乎是在密码验证中。
以下是我用来创建用户的代码:
var userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
var user = new ApplicationUser { UserName = "user@domain.tdl", Email = "user@domain.tdl" };
var userPassword = "p455W@rd";
var userCheck = userManager.Create(user, userPassword);
已经创建了用户,但是当我尝试使用密码登录时,登录失败。
我实际上已经将该用户植入了我的数据库,以便仅出于本篇文章的目的获得实际的哈希值。
使用下面的代码(我从带有ILSpy的ASP.NET Identity中取出)来验证密码,此哈希密码和纯文本密码匹配。
(如果需要,您可以将此代码直接复制到dotnetfiddle中。)
但是,我以完全相同的方式创建了一个登录名,该登录名的哈希密码和纯文本密码未通过此验证。
有什么主意为什么会生成无法解析回原始值的哈希?
public static void Main()
{
var hashedPassword = "AA29ol/cj3GsR+yEjQWcQufmOvJCy7kZMIiSTMfxCdeXpeeLy2npjVpndBlfRS8kxQ==";
var password = "p455W@rd";
var array = Convert.FromBase64String(hashedPassword);
if (array.Length != 49 || array[0] != 0)
{
Console.WriteLine("Array length wasn't 49 or the first item in the array wasn't 0");
}
var array2 = new byte[16];
Buffer.BlockCopy(array, 1, array2, 0, 16);
var array3 = new byte[32];
Buffer.BlockCopy(array, 17, array3, 0, 32);
byte[] bytes;
using (Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(password, array2, 1000))
{
bytes = rfc2898DeriveBytes.GetBytes(32);
}
var equals = ByteArraysEqual(array3, bytes);
if (equals)
{
Console.WriteLine("Arrays equal");
}
else
{
Console.WriteLine("Arrays do not equal");
}
}
public static bool ByteArraysEqual(byte[] a, byte[] b)
{
if (object.ReferenceEquals(a, b))
{
return true;
}
if (a == null || b == null || a.Length != b.Length)
{
return false;
}
bool flag = true;
for (int i = 0; i <a.Length; i++)
{
flag &= (a[i] == b[i]);
}
return flag;
}