1

我正在使用 Python 的 crypt 包将加密密码保存在 Django 网站的 MySQL 数据库中。我不确定这是否是一个错误,但这是我正在使用的代码:

加密/保存密码:

user.password = crypt(request.POST['password'], netid)
user.save()

要在登录时检查正确的密码:

if crypt(password, email) == user.password:
# Grant acccess to the user's profile, etc.

问题如下。netid = test@example.com如果我用变量and加密密码request.POST['password'] = 'ABC123abc',它工作正常。但是,当我尝试登录时,如果我使用密码'ABC123abc[trailing_chars]',其中 trailing_chars 可以是任何有效字符串,我仍然能够登录。这是为什么?它构成了一个很大的安全漏洞。

4

1 回答 1

6

首先,您应该使用电子邮件地址作为 crypt 的盐(第二个参数)。这是不安全的。你必须选择一个好的随机盐。

对于传统的 crypt,salt 是从 set 中选择的两个字符的字符串[a–zA–Z0–9./]。此版本的 crypt 仅接受 8 个输入字符,并在第 8 个之后从输入中丢弃所有后续字符。这就是你在这里看到的。

现代 crypt 实现还支持在密码学上比传统 crypt 强大得多的其他算法,但它们并非在所有平台上都可用。新算法也不将输入限制为 8 个字符。

要使用其中一种更好的算法(如果您使用的是支持它们的平台),您需要提供一种特殊格式的盐。这就是函数识别您想要使用替代算法的方式。

对于 glibc 支持的额外算法(因此在 GNU/Linux 上可用),请参阅crypt 手册页的“Glibc 注释”部分。

顺便说一句,在检查密码时,您不需要手动提取盐。加密密码已经以 salt 开头,所以只需将user.password(not email) 作为第二个参数传递给crypt. 无论您使用的是旧算法还是新算法之一,这都有效。只有在加密密码时才需要选择算法和生成正确格式的盐,而不是在验证密码时。

于 2013-01-11T18:43:10.520 回答