35.5. crypt
—检查Unix密码的功能¶
源代码: Lib/crypt.py
该模块实现了 crypt(3) 例程的接口,该例程是基于修改的DES算法的单向散列函数;有关更多详细信息,请参阅Unix手册页。可能的用途包括存储散列密码,以便您可以在不存储实际密码的情况下检查密码,或尝试使用字典破解Unix密码。
请注意,此模块的行为取决于运行系统中 crypt(3) 例程的实际实现。因此,当前实现中可用的任何扩展也将在此模块上可用。
35.5.1. 散列方法¶
3.3 新版功能.
crypt
模块定义了哈希方法列表(并非所有平台上的所有方法都可用):
-
crypt.
METHOD_SHA512
¶ 一个16字符盐和86字符哈希的模块化地址格式方法。这是最强的方法。
-
crypt.
METHOD_SHA256
¶ 另一个模块化地址格式方法,具有16个字符的盐和43个字符的哈希。
-
crypt.
METHOD_MD5
¶ 另一个模块化地址格式方法,具有8个字符的盐和22个字符的哈希。
-
crypt.
METHOD_CRYPT
¶ 传统方法使用2个字符的盐和13个字符的哈希。这是最弱的方法。
35.5.3. 模块功能¶
crypt
模块定义以下功能:
-
crypt.
crypt
(word, salt=None)¶ word 通常是在提示符或图形界面中键入的用户密码。可选的 salt 是从
mksalt()
返回的字符串,crypt.METHOD_*
值之一(尽管不是所有平台都可用),或者是由此函数返回的包含salt的完全加密密码。如果不提供 salt,将使用最强的方法(由methods()
返回。检查密码通常是通过传递明文密码作为 word 和以前的
crypt()
调用的完整结果,应该与此调用的结果相同。salt (随机的2或16个字符的字符串,可能带有
$digit$
的前缀以指示该方法),这将用于扰乱加密算法。 salt 中的字符必须在集合[./a-zA-Z0-9]
中,除了前缀$digit$
的模块加密格式例外。以字符串形式返回散列的密码,该字符串将由与盐相同的字母表中的字符组成。
由于少数 crypt(3) 扩展允许不同的值,在 salt 中具有不同的大小,因此建议在检查密码时使用完全加密的密码作为盐。
在 3.3 版更改: 除了 salt 的字符串之外,还接受
crypt.METHOD_*
值。
35.5.4. 例子¶
一个简单的例子说明典型的使用(需要恒定时间比较操作来限制暴露于定时攻击) hmac.compare_digest()
适用于此目的):
import pwd
import crypt
import getpass
from hmac import compare_digest as compare_hash
def login():
username = input('Python login: ')
cryptedpasswd = pwd.getpwnam(username)[1]
if cryptedpasswd:
if cryptedpasswd == 'x' or cryptedpasswd == '*':
raise ValueError('no support for shadow passwords')
cleartext = getpass.getpass()
return compare_hash(crypt.crypt(cleartext, cryptedpasswd), cryptedpasswd)
else:
return True
使用最强的可用方法生成密码的哈希值,并对照原始值:
import crypt
from hmac import compare_digest as compare_hash
hashed = crypt.crypt(plaintext)
if not compare_hash(hashed, crypt.crypt(plaintext, hashed)):
raise ValueError("hashed version doesn't validate against original")