PHP的crypt()中的md5hash密码是否可移植到Django密码字段?

2024-10-03 13:26:57 发布

您现在位置:Python中文网/ 问答频道 /正文

我将一堆用户帐户从一个遗留的PHP网站移植到一个新的、闪亮的基于Django的站点。一组密码存储为PHP的^{}函数的MD5散列输出(见第三个例子)。在

给定来自旧版应用程序的密码哈希:

$1$f1KtBi.v$nWwBN8CP3igfC3Emo0OB8/

如何将其转换为^{}的Django形式?crypt()MD5输出似乎使用了与Django的MD5支持不同的字母表(它似乎使用了hexdigest)。在

更新:

有一个similar (and unanswered) question有一个有趣的潜在解决方案,可以将PHP散列转换为base-16编码,但是基于一些初始的插入,它似乎无法生成可用的MD5 hexdigest。:(

具体例子:

一个具体的例子可能会有所帮助。在

给予:

  • 密码foo
  • 一种$1$aofigrjlh的盐

在PHP中,crypt('foo', '$1$aofigrjlh')生成一个$1$aofigrjl$xLnO.D8x064D1kDUKWwbX.的散列。在

crypt()在MD5模式下运行,但它是MD5算法的一些wacky Danish translation更新:它是MD5 Crypt)。由于Python是一个Dutch-derived language,Python的crypt模块只支持DES风格的散列。在

在Python中,我需要能够在给定原始密码和salt的情况下,重新生成该散列,或者对其进行常规派生。在


Tags: django函数用户密码foo站点网站帐户
3条回答

不幸的是,不可能将这些转换成Django的格式(尽管有一个可能的路径可以导入散列,详细信息如下)。在

Django的salted md5算法使用一个非常简单的算法:md5(salt + password),然后将其编码为十六进制。在

另一方面,PHP的crypt()$1$开头的散列不是简单的md5哈希。相反,它们使用一种称为MD5-Crypt的密码哈希算法。这比简单的md5哈希要复杂得多(而且安全)。链接页面中有一个部分描述了MD5 Crypt格式和算法。无法将其转换为Django的格式,因为它在代码中不提供对算法的支持。在

虽然Django的代码名为Python的stdlib crypt()函数,但Django对散列的处理方式意味着没有一种简单的方法可以在Django中得到以$1$开头的散列,直到crypt();这是向{}发出信号,表示您希望使用MD5 Crypt而不是旧的DES Crypt的唯一方法。在


但是,有一种可能的方法:可以使用monkeypatchdjango.contrib.auth.models.User,这样它既支持普通的Django哈希,也支持MD5 Crypt格式。这样您就可以不加更改地导入哈希。一种方法是手动执行此操作,方法是重写User.set_passwordUser.check_password方法。在

另一种选择是使用Passlib库,其中包含一个Django应用程序,该应用程序旨在处理所有这些问题,并为md5crypt等提供跨平台支持。(免责声明:我是该库的作者)不幸的是Django插件是没有文档记录的,因为我在自己的Django部署之外没有对它进行过太多的测试。。。尽管它对他们来说很好:)(在source中有一些beta文档)edit:从Passlib 1.6开始,这是一个正式发布的扩展,documented。在

要使用它,请安装passlib,并将passlib.ext.django添加到已安装应用程序的列表中。然后,在settings.py中添加以下内容:

PASSLIB_CONFIG = """
[passlib]
schemes =
    md5_crypt,
    django_salted_sha1, django_salted_md5,
    django_des_crypt, hex_md5,
    django_disabled

default = md5_crypt

deprecated = django_des_crypt, hex_md5
"""

这将重写User.set_passwordUser.check_password以使用Passlib而不是内置代码。上面的配置字符串将passlib配置为模拟Django的内置散列,但随后添加了对md5_crypt的支持,因此您的哈希应该按原样接受。在

我正在从WordPress2.8迁移到Django1.8。当我发现wordpress2.8(可能还有未来的版本)以MD5加密格式(phpass库)存储密码。我尝试了django1.8的passlib扩展,但它对我不起作用。所以我最终用MD5加密算法编写了自定义哈希器。在

注意:在迁移过程中,将“md5_crypt”添加到密码哈希(user_pass字段)

我将MD5CryptPasswordHasher添加到列表的顶部以使其成为默认值(为了不混淆不同的哈希算法,如果我再次迁移到另一个平台呢?)但是,如果一个人只想为现有用户添加对该算法的支持,但强制新用户迁移到PBKDF2PasswordHasher哈希器或其他方法,则可以将其添加到列表的底部。在

设置.py

PASSWORD_HASHERS = (
    'your_project_name.hashers.MD5CryptPasswordHasher',
    '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.UnsaltedSHA1PasswordHasher',
    'django.contrib.auth.hashers.UnsaltedMD5PasswordHasher',
    'django.contrib.auth.hashers.CryptPasswordHasher',
)

hashers.py

^{pr2}$

看看passlib.hash.md5_crypt,这是由令人敬畏的passlib项目设计的。在

相关问题 更多 >