在MySQL中生成加密密码,以填充Django数据库

3 投票
1 回答
1614 浏览
提问于 2025-04-29 00:26

这是一个我已经有了一个还不错的解决方案的问题,所以我在这里发帖看看有没有人能帮我改进。

我正在把客户的数据从一个旧的定制系统(mysql数据库,密码是明文存储的!!)迁移到django。这个数据迁移将完全通过一组sql脚本来完成,这些脚本可以在两个数据库上运行(将旧数据库的数据移动和转换到新数据库)。这个过程需要是可重复的、可预测的,并且能够在无人值守的情况下运行。

我需要把现有的密码加密,并以django可以接受的格式存储(具体细节可以查看这里)。理想情况下,我想使用django推荐的PBKDF2加密方式来处理这个问题,但这很难,因为我无法轻松模拟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 个回答

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)

撰写回答