我们有一个当前应用程序,其中用户登录凭据存储在 SQL Server 数据库中。这些基本上存储为纯文本用户名、密码散列和此散列的关联盐。
这些都是由 ASP.NET 的成员/角色系统中的内置函数创建的。这是名为“joe”的用户和密码“password”的一行:
乔,kDP0Py2QwEdJYtUX9cJABg==,OJF6H4KdxFLgLu+oTDNFodCEfMA=
我已将这些内容转储到 CSV 文件中,并试图将其转换为 Django 的可用格式,该格式以这种格式存储其密码:
[算法]$[盐]$[哈希]
其中盐是纯字符串,散列是 SHA1 散列的十六进制摘要。
到目前为止,我已经能够确定 ASP 正在以 base64 格式存储这些哈希和盐。上面的那些值解码成二进制字符串。
我们使用反射器来收集 ASP 如何根据这些值进行身份验证:
internal 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[] dst = new byte[src.Length + bytes.Length];
byte[] inArray = null;
Buffer.BlockCopy(src, 0, dst, 0, src.Length);
Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length);
if (passwordFormat == 1)
{
HashAlgorithm algorithm = HashAlgorithm.Create(Membership.HashAlgorithmType);
if ((algorithm == null) && Membership.IsHashAlgorithmFromMembershipConfig)
{
RuntimeConfig.GetAppConfig().Membership.ThrowHashAlgorithmException();
}
inArray = algorithm.ComputeHash(dst);
}
else
{
inArray = this.EncryptPassword(dst);
}
return Convert.ToBase64String(inArray);
}
本质上,从数据库中提取盐,然后 b64 将其解码为二进制表示。它对原始密码执行“GetBytes”,然后将它们连接起来,首先是盐。
然后它在这个新字符串上运行 SHA1 算法,base64 对其进行编码,并将其与存储在数据库中的值进行比较。
我试图编写一些代码来尝试在 Python 中重现这些哈希值,但我失败了。在我弄清楚它是如何翻译的之前,我将无法在 Django 中使用它们。这是我的测试方式:
import hashlib
from base64 import b64decode, b64encode
b64salt = "kDP0Py2QwEdJYtUX9cJABg=="
b64hash = "OJF6H4KdxFLgLu+oTDNFodCEfMA="
binsalt = b64decode(b64salt)
password_string = 'password'
m1 = hashlib.sha1()
# Pass in salt
m1.update(binsalt)
# Pass in password
m1.update(password_string)
# B64 encode the binary digest
if b64encode(m1.digest()) == b64hash:
print "Logged in!"
else:
print "Didn't match"
print b64hash
print b64encode(m1.digest())
我想知道是否有人可以看到我的方法中的任何缺陷或可以提出替代方法。也许您可以使用上面的算法以及上面的已知密码和盐并在您的系统上生成哈希?