Python crypt包:可以在密码中输入额外的字符

时间:2013-01-11 18:28:08

标签: python django unix encryption crypt

我正在使用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.comrequest.POST['password'] = 'ABC123abc'加密密码,则可以正常使用。但是,当我尝试登录时,如果我使用密码'ABC123abc[trailing_chars]',其中trailing_chars可以是任何有效字符串,我仍然可以登录。为什么会这样?它本身就是一个很大的安全漏洞。

1 个答案:

答案 0 :(得分:6)

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

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

现代加密实现还支持其他算法,这些算法在加密方面比传统加密更强大,但它们并非在所有平台上都可用。新算法也不会将输入限制为8个字符。

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

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

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