2014-10-22 74 views
2

这是我已经有一个过得去的答案的一个问题 - 所以我在这里发帖,看是否有人能够改善它。生成在MySQL加密口令,来填充Django的数据库

我从旧的定制系统迁移的客户数据(MySQL数据库与明文密码!)在模块中使用。数据迁移只能使用一组可以针对两个数据库运行的sql脚本(将数据从旧数据库移动到新数据库)。该流程需要可重复,可预测并且可能无人值守运行。

我需要采取现有密码,加密,并将它们存储在一个格式是可接受的Django(见详情here)。理想情况下,我会使用django的首选PBKDF2 hasher来做到这一点,但这很难,因为我无法轻松模拟PBKDF2所做的密码延伸/多次迭代。

我现在的解决方法是盐和使用SHA1加密明文密码,并将它们存储在Django。然后,客户第一次登录时,Django会自动将密码加密升级到PBKDF2。

我想为此使用SHA2/SHA256,但是Django在没有PBKDF2的情况下不支持此功能,至少除非我编写自己的密码哈希后端并将其添加到django settings.py - 这似乎很多努力。

因此,我到了在我的移民sql脚本如下(简化为清楚起见):

insert into auth_user(username,password) 

SELECT username 
    , CONCAT(
    'sha1$', 
    @salt := SUBSTRING(MD5(RAND()) FROM 1 FOR 12), 
    '$', SHA1(CONCAT(@salt,password)) 
    ) AS password 
FROM 
    old_user_table; 

,其输出密码字符串是这样的:

sha1$a6acb1163c50$e7225b82280d66b4d8125cb7817b7854e98a5657 

到目前为止,它的工作原理对待 - 用户可以登录并且加密是静默升级的。唯一的缺点是我们正在使用相对不安全的SHA1算法,至少在用户登录一次之前。

任何人都可以改进此解决方案吗?

回答

1

你有明文密码,所以你可以通过所有的用户编写一个简单的脚本进行迭代,并验证它们。在迁移sql脚本之后运行此操作,这会在您将其暴露给真实用户之前升级每个用户的密码,从而减轻您对降低安全性的担忧。

from django.contrib.auth import authenticate 

for username, password in get_usernames_and_passwords(): 
    if authenticate(username=username, password=password) is None: 
     print "Failed to authenticate user {!r}".format(username) 
+0

这是一个好主意,虽然它不符合我的要求,一切都可以通过一组sql语句完成。 还是谢谢! – 2014-10-22 11:48:33

+0

我并不知道你的环境,也没有限制的原因,但是,必须调用mysql才能运行sql迁移脚本......可能是一个运行类似于上述迁移后代码的Python脚本。 – mhawke 2014-10-22 11:56:39

+0

没有限制,我只是不想向django项目添加代码并处理部署等。现在迁移过程是纯sql,因此易于独立于开发团队运行。我将从我最喜欢的MySQL GUI(SQlyog)中运行它。 你的解决方案仍然是一个很好的解决方案,它只是不适合我想要做的事情。但我可能仍然会执行它! – 2014-10-22 14:28:58