【问题标题】:python django unsalted md5 password hash formatpython django unsalted md5密码哈希格式
【发布时间】:2023-03-14 17:24:01
【问题描述】:

我从一个旧的 php 应用程序中获得了一个用户表,其中用户使用未加盐的 md5 哈希作为密码,并且因为我正在将应用程序迁移到 django,我试图将所有用户放在 auth_user 表中。

参考this 帖子,可以将密码存储为不加盐的 md5 哈希。但这对我不起作用? (python/2.7.6,django/1.6.1)

例如对于具有密码“changeme”的用户,我认为它的格式应该是 md5$$4cb9c8a8048fd02294477fcb1a41191a 还是我遗漏了什么?

编辑: 在 settings.py 我得到了:

PASSWORD_HASHERS = (
    'django.contrib.auth.hashers.PBKDF2PasswordHasher',
    'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
    'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
    'django.contrib.auth.hashers.BCryptPasswordHasher',
    'django.contrib.auth.hashers.SHA1PasswordHasher',
    'django.contrib.auth.hashers.MD5PasswordHasher',
    'django.contrib.auth.hashers.CryptPasswordHasher',
)

我在 views.py 中使用 login_required 装饰器(如果有某种关联):

@login_required
def index(request):
    logger.debug('index accessed from %s by %s' % (request.META.get('REMOTE_ADDR'), request.user.username) )
    member = members.objects.get(nickname=request.user.username)
    context = {'request': request, 'member': member}
    return render(request, 'voip/index.html', context)

和以下 urls.py:

url(r'^login/$', 'django.contrib.auth.views.login', {
  'template_name': 'voip/login.html'
}),
url(r'^logout/$', 'django.contrib.auth.views.logout_then_login', {
  #'template_name': 'voip/logout.html'
}),

只要在 settings.py AUTHENTICATION_BACKENDS 看起来像这样,它就可以工作:

AUTHENTICATION_BACKENDS = (
    'django.contrib.auth.backends.ModelBackend',
    'django_auth_ldap.backend.LDAPBackend',
)

只要我注释掉 django_auth_ldap 它就不起作用。但是如果我随后将 pbkdf2 哈希从最初安装的超级用户(我设置 pw changeme 进行调试)复制到 auth_user 表中我自己的用户,我可以使用密码“changeme”登录...

【问题讨论】:

    标签: python django passwords md5


    【解决方案1】:

    您可以自定义身份验证过程,甚至可以编写自定义身份验证后端。官方文档中涵盖了该主题:

    https://docs.djangoproject.com/en/1.6/topics/auth/customizing/

    【讨论】:

    • 好吧,我知道这一点并考虑编写自定义后端,但后来我阅读并注意到,django 使用新的哈希自动更新密码。所以我只需要知道如何将用户的旧 md5 哈希值存储在表 auth_user 中以编写一次并让 django 完成它的工作。我已经获得了所需的所有其他信息,只是身份验证失败并且我不确定如何正确存储 md5 哈希。
    【解决方案2】:

    对于您的问题,我有两个建议。

    首先,请在settings.py 中查看PASSWORD_HASHERS。 Django 能够从旧算法升级密码,但前提是它们在您的配置中可用。阅读更多at the django docs

    至少你需要激活MD5PasswordHasher

    PASSWORD_HASHERS = (
        'django.contrib.auth.hashers.PBKDF2PasswordHasher',
        'django.contrib.auth.hashers.MD5PasswordHasher',
    )
    

    其次,如果您已经这样做了,您可以尝试简单地存储旧的 MD5 密码,而不用前导 md5$$。这也被支持作为后备。 Django 会将 32 位十六进制数识别为 MD5 哈希。这是来自django source code的相关代码块:

    # Ancient versions of Django created plain MD5 passwords and accepted
    # MD5 passwords with an empty salt.
    if ((len(encoded) == 32 and '$' not in encoded) or
            (len(encoded) == 37 and encoded.startswith('md5$$'))):
        algorithm = 'unsalted_md5'
    

    希望这会有所帮助!

    【讨论】:

    • 感谢您指出这一点,尝试使用和不使用md5$$,但都不起作用。我用我的 password_hashers 设置编辑了我的帖子。因为我在网上找不到太多关于此类问题的信息,所以我想更多的是它只是我这边的一些问题,但是我可以在哪里挖掘到某个点可能会在这件事上失败?因为我没有看到任何错误或类似的,根本无法验证...
    【解决方案3】:

    根据我在 Django 1.6.1 源代码中看到的内容,您不能将 MD5PasswordHasher 与空盐一起使用:https://github.com/django/django/blob/1.6.1/django/contrib/auth/hashers.py#L397

    但是UnsaltedMD5PasswordHasher 可能对你有用。

    编辑:您提到的answer 是 4 年前 Django 1.2 统治市场时编写的。我检查了它的password hashing code,它没有任何断言,这就是为什么 MD5 哈希器当时使用空盐。

    【讨论】:

    • 非常感谢,解决了我的问题,登录成功! :) 太棒了!
    猜你喜欢
    • 2011-02-11
    • 1970-01-01
    • 2020-09-16
    • 2012-03-28
    • 2013-06-17
    • 1970-01-01
    • 2019-07-10
    • 2016-10-29
    • 2014-11-05
    相关资源
    最近更新 更多