asp.net - 使用 Python 对 ASP.NET 角色/成员身份创建的数据库中的原始用户名、散列、盐进行身份验证

标签 asp.net python hash passwords

我们有一个当前的应用程序,其中用户登录凭据存储在 SQL Server 数据库中。这些基本上存储为纯文本用户名、密码哈希和该哈希的关联盐。

这些都是由 ASP.NET 的成员/角色系统中的内置函数创建的。这是名为“joe”的用户和密码“password”的一行:

joe,kDP0Py2QwEdJYtUX9cJABg==,OJF6H4KdxFLgLu+oTDNFodCEfMA=

我已将这些内容转储到一个 CSV 文件中,并试图将其转换为 Django 可用的格式,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())

我想知道是否有人可以看到我的方法中的任何缺陷或可以建议替代方法。也许您可以采用上面的算法以及上面已知的密码和盐,并在您的系统上生成哈希?

最佳答案

当您将 UTF16 字符串转换为二进制时,python 似乎插入了一个字节顺序标记。 .NET 字节数组不包含 BOM,所以我做了一些 ghetto python 将 UTF16 转换为十六进制,删除前 4 个字符,然后将其解码为二进制。

可能有更好的方法来删除 BOM,但这对我有用!

这是通过的:

import hashlib
from base64 import b64decode, b64encode

def utf16tobin(s):
  return s.encode('hex')[4:].decode('hex')

b64salt = "kDP0Py2QwEdJYtUX9cJABg=="
b64hash = "OJF6H4KdxFLgLu+oTDNFodCEfMA="
binsalt = b64decode(b64salt)
password_string = 'password'.encode("utf16")
password_string = utf16tobin(password_string)

m1 = hashlib.sha1()
# Pass in salt
m1.update(binsalt + password_string)
# Pass in password
# B64 encode the binary digest
if b64encode(m1.digest()) == b64hash:
    print "Logged in!"
else:
    print "Didn't match"
    print b64hash
    print b64encode(m1.digest())

关于asp.net - 使用 Python 对 ASP.NET 角色/成员身份创建的数据库中的原始用户名、散列、盐进行身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/269713/

相关文章:

asp.net - .CSHTML 页面不会呈现

c# - ASP.Net MVC 中错误模型的编译时错误

javascript - WebControl在<script>标签中创建JS对象,如何获取页面JS中的对象?

python - Selenium Python 单击 Javascript 弹出窗口上的按钮不执行任何操作

perl - 为什么 Perl 认为存在不存在的多级哈希元素?

c# - 在类里面使用 session

python - 和 Python 列表上的运算符

python - 如何使用 Tox 和 Poetry 在 CircleCI 中设置多个解释器?

javascript - v8 如何对哈希表中的键进行哈希处理

php - PHP 密码的安全散列和盐