来自 PHP crypt() 的 MD5 哈希密码是否可以移植到 Django 密码字段?
我正在将一堆用户帐户从旧的 PHP 网站移植到一个新的、基于 Django 的网站。一堆密码存储为 PHP crypt()
函数(参见第三个示例)。
给定来自遗留应用程序的密码哈希:
$1$f1KtBi.v$nWwBN8CP3igfC3Emo0OB8/
我如何将其转换为 md5$<盐>$<哈希>
? crypt()
MD5 输出似乎使用与 Django 的 MD5 支持不同的字母表(它似乎使用十六进制摘要)。
更新:
有一个类似(且未回答)的问题有一个有趣的潜在解决方案,可以将 PHP 哈希转换为 base-16 编码,但基于一些初步的研究,它似乎没有产生可用的 MD5 十六进制摘要。 :(
具体示例:
具体示例可能会有所帮助。
给定:
foo
的密码$1$aofigrjlh
在 PHP 中,crypt('foo', '$1$aofigrjlh')
产生一个哈希值$1$aofigrjl$xLnO.D8x064D1kDUKWwbX.
。
crypt()
正在MD5模式下运行,但它是一些MD5 算法的古怪丹麦语翻译(更新: MD5-Crypt)。由于 Python 是一种源自荷兰语的语言,因此 Python 的 crypt
模块仅支持 DES 风格的散列,
在 Python 中,我需要能够在给定原始密码和盐的情况下重现该散列或它的一些常规推导。
I'm porting a bunch of user accounts from a legacy PHP website to a new and shiny Django-based site. A bunch of the passwords are stored as the MD5 hash output from PHP's crypt()
function (see the third example there).
Given this password hash from the legacy application:
$1$f1KtBi.v$nWwBN8CP3igfC3Emo0OB8/
How might I convert it to the Django form of md5$<salt>$<hash>
? The crypt()
MD5 output seems to use a different alphabet than Django's MD5 support (which appears to be using a hexdigest).
Update:
There's a similar (and unanswered) question with an interesting potential solution to convert the PHP hash to a base-16 encoding, but based on some initial poking, it doesn't seem to produce a usable MD5 hexdigest. :(
Concrete example:
A concrete example might help.
Given:
- a password of
foo
- a salt of
$1$aofigrjlh
In PHP, crypt('foo', '$1$aofigrjlh')
produces a hash of $1$aofigrjl$xLnO.D8x064D1kDUKWwbX.
.
crypt()
is operating in MD5 mode, but it's some wacky Danish translation of the MD5 algorithm (Update: It's MD5-Crypt). Since Python is a Dutch-derived language, Python's crypt
module only supports the DES-style of hashing.
In Python, I need to be able to reproduce that hash, or some regular derivation of it, given the original password and salt.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
不幸的是,不可能将它们转换为 Django 的格式(尽管您可以采取一种可能的途径来导入哈希值,详细信息如下)。
Django 的 salted md5 算法使用非常简单的算法:
md5(salt+password)
,然后将其编码为十六进制。另一方面,PHP 的
crypt()
输出的以$1$
开头的哈希值并不是简单的 md5 哈希值。相反,他们使用名为 MD5-Crypt 的密码哈希算法。这比简单的 md5 哈希要复杂(也安全)得多。链接页面中有一个部分描述了 MD5-Crypt 格式和格式。算法。无法将其转换为 Django 的格式,因为它不提供对其代码中算法的支持。虽然 Django 确实有调用 Python 的 stdlib
crypt()
函数的代码,但 Django 破坏散列的方式意味着没有简单的方法来获取以$1$ 开头的散列
一路通过 Django 并进入crypt()
;这是向crypt()
发出信号表明您想要使用 MD5-Crypt 而不是旧的 DES-Crypt 的唯一方法。但是,有一个可能的途径:您可以对 django.contrib.auth.models.User 进行 Monkeypatch,以便它支持普通的 Django 哈希值以及 MD5-Crypt 格式。这样您就可以原样导入哈希值。一种方法是通过重写 User.set_password 和 User.check_password 方法来手动执行此操作。
另一种选择是使用 Passlib 库,其中包含一个 Django 应用程序,旨在处理所有这些问题,以及为 md5-crypt 等提供跨平台支持。 (免责声明:我是该库的作者)。
不幸的是,Django 插件没有文档记录,因为我没有在我自己的 django 部署之外对其进行太多测试...尽管它对它们来说工作得很好:)(源)编辑:从 Passlib 1.6 开始,此扩展现已正式发布,并且 记录。要使用它,请安装 passlib,并将
passlib.ext.django
添加到已安装应用程序列表中。然后,在settings.py
中添加以下内容:这将覆盖
User.set_password
和User.check_password
以使用 Passlib 而不是内置代码。上面的配置字符串将 passlib 配置为模仿 Django 的内置哈希值,但随后添加了对 md5_crypt 的支持,因此您的哈希值应该按原样接受。Unfortunately, it isn't possible to convert those over to Django's format (though there is a possible route you can take that will get your hashes imported, detailed below).
Django's salted md5 algorithm uses a very simple algorithm:
md5(salt + password)
, which is then encoded to hexidecimal.On the other hand, the hashes output by PHP's
crypt()
which begin with$1$
are not simple md5 hashes. Instead, they use a password hashing algorithm known as MD5-Crypt. This is much more complex (and secure) than a simple md5 hash. There's a section in the linked page which describes the MD5-Crypt format & algorithm. There is no way to translate it into Django's format, as it doesn't offer support for the algorithm within it's code.While Django does have code which called Python's stdlib
crypt()
function, the way Django mangles the hashes means there's no easy way to get a hash beginning with$1$
all the way through Django and intocrypt()
; and that's the only way to signal tocrypt()
that you want to use MD5-Crypt instead of the older DES-Crypt.However, there is a possible route: you can monkeypatch
django.contrib.auth.models.User
so that it supports both the normal Django hashes, as well as the MD5-Crypt format. That way you can import the hashes unchanged. One way is to do this manually, by overriding theUser.set_password
andUser.check_password
methods.Another alternative is to use the Passlib library, which contains a Django app that was designed to take care of all this, as well as provide cross-platform support for md5-crypt et al. (Disclaimer: I'm the author of that library).
Unfortunately that Django plugin is undocumented, because I haven't tested it much outside of my own django deploys... though it works fine for them :) (There is some beta documentation in the source)edit: As of Passlib 1.6, this is extension is now officially released and documented.In order to use it, install passlib, and add
passlib.ext.django
to your list of installed apps. Then, withinsettings.py
, add the following:This will override
User.set_password
andUser.check_password
to use Passlib instead of the builtin code. The configuration string above configures passlib to mimic Django's builtin hashes, but then adds support for md5_crypt, so your hashes should then be accepted as-is.查看 passlib.hash.md5_crypt,作者:passlib 项目。
Check out passlib.hash.md5_crypt, by the awesome passlib project.
我正在从 Wordpress 2.8 迁移到 Django 1.8。我发现 Wordpress 2.8(可能还有未来的版本)以 MD5 加密格式(phpass 库)存储密码。我尝试了 Django 1.8 的 passlib 扩展,但它对我不起作用。所以我最终用 MD5 加密算法编写了自定义哈希器。
注意:在迁移过程中,将“md5_crypt”添加到密码哈希(user_pass 字段)中,
我将 MD5CryptPasswordHasher 添加到列表顶部以使其成为默认值(为了不混淆不同的哈希算法,如果我再次迁移到另一个平台怎么办? )但如果只想为现有用户添加对算法的支持但强制新用户迁移到 PBKDF2PasswordHasher 哈希器或其他算法,则可以将其添加到列表底部。
settings.py
hashers.py
I am in process of migrating from Wordpress 2.8 to Django 1.8. As I found out Wordpress 2.8 (and probably future versions as well) stores password in MD5 crypto format (phpass library). I tried passlib extension for Django 1.8 but it didn't work for me. So I ended up writing custom hasher with MD5 crypto algorithm.
NOTE: During migration add "md5_crypt" to password hash (user_pass field)
I added MD5CryptPasswordHasher to the top of the list to make it default (in order not to mix up different hashing algorithms, what if I will migrate once again to another platform?) but it can be added to the bottom of the list if one just want to add support for the algorithm for existing users but force new users to migrate to PBKDF2PasswordHasher hasher or other.
settings.py
hashers.py