Skip to main content
 首页 » 编程设计

Python crypt 包 : Can type extra characters in password

2025年05月04日19soundcode

我正在使用 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 和 request.POST['password'] = 'ABC123abc' 加密密码,它工作正常。但是,当我尝试登录时,如果我使用密码 'ABC123abc[trailing_chars]',其中 trailing_chars 可以是任何有效字符串,我仍然能够登录。这是为什么?它构成了一个巨大的安全漏洞。

请您参考如下方法:

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

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

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

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

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

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