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

Mat*_*ern 1 python unix encryption django crypt

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

要加密/保留密码:

user.password = crypt(request.POST['password'], netid)
user.save()
Run Code Online (Sandbox Code Playgroud)

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

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

问题如下.如果我有可变密码进行加密netid = test@example.comrequest.POST['password'] = 'ABC123abc',它工作正常.但是,当我尝试登录时,如果我使用密码'ABC123abc[trailing_chars]',其中trailing_chars可以是任何有效的字符串,我仍然可以登录.为什么会这样?它本身就是一个很大的安全漏洞.

Cel*_*ada 6

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

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

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

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

对于glibc支持的额外算法(因此可在GNU/Linux上使用),请参阅crypt手册页的"Glibc Notes"部分.

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