我将一堆用户帐户从一个遗留的PHP网站移植到一个新的、闪亮的基于Django的站点。一组密码存储为PHP的^{
给定来自旧版应用程序的密码哈希:
$1$f1KtBi.v$nWwBN8CP3igfC3Emo0OB8/
如何将其转换为^{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的情况下,重新生成该散列,或者对其进行常规派生。在
不幸的是,不可能将这些转换成Django的格式(尽管有一个可能的路径可以导入散列,详细信息如下)。在
Django的salted md5算法使用一个非常简单的算法:
md5(salt + password)
,然后将其编码为十六进制。在另一方面,PHP的
crypt()
以$1$
开头的散列不是简单的md5哈希。相反,它们使用一种称为MD5-Crypt的密码哈希算法。这比简单的md5哈希要复杂得多(而且安全)。链接页面中有一个部分描述了MD5 Crypt格式和算法。无法将其转换为Django的格式,因为它在代码中不提供对算法的支持。在虽然Django的代码名为Python的stdlib}发出信号,表示您希望使用MD5 Crypt而不是旧的DES Crypt的唯一方法。在
crypt()
函数,但Django对散列的处理方式意味着没有一种简单的方法可以在Django中得到以$1$
开头的散列,直到crypt()
;这是向{但是,有一种可能的方法:可以使用monkeypatch
django.contrib.auth.models.User
,这样它既支持普通的Django哈希,也支持MD5 Crypt格式。这样您就可以不加更改地导入哈希。一种方法是手动执行此操作,方法是重写User.set_password
和User.check_password
方法。在另一种选择是使用Passlib库,其中包含一个Django应用程序,该应用程序旨在处理所有这些问题,并为md5crypt等提供跨平台支持。(免责声明:我是该库的作者)。
不幸的是Django插件是没有文档记录的,因为我在自己的Django部署之外没有对它进行过太多的测试。。。尽管它对他们来说很好:)(在source中有一些beta文档)edit:从Passlib 1.6开始,这是一个正式发布的扩展,documented。在要使用它,请安装passlib,并将
passlib.ext.django
添加到已安装应用程序的列表中。然后,在settings.py
中添加以下内容:这将重写
User.set_password
和User.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
hashers.py
^{pr2}$看看passlib.hash.md5_crypt,这是由令人敬畏的passlib项目设计的。在
相关问题 更多 >
编程相关推荐