35.5. crypt
—— 检查 Unix 口令的函数¶
源代码: Lib/struct.py
本模块实现了连接 crypt(3) 的接口,是一个基于改进 DES 算法的单向散列函数;更多细节请参阅 Unix man 手册。可能的用途包括保存经过哈希的口令,这样就可以在不存储实际口令的情况下对其进行验证,或者尝试用字典来破解 Unix 口令。
请注意,本模块的执行取决于当前系统中 crypt(3) 的实际实现。 因此,当前实现版本可用的扩展均可在本模块使用。
35.5.1. 哈希方法¶
3.3 版新加入.
crypt
模块定义了哈希方法的列表(不是所有的方法在所有平台上都可用)。
-
crypt.
METHOD_SHA512
¶ A Modular Crypt Format method with 16 character salt and 86 character hash. This is the strongest method.
-
crypt.
METHOD_SHA256
¶ Another Modular Crypt Format method with 16 character salt and 43 character hash.
-
crypt.
METHOD_MD5
¶ Another Modular Crypt Format method with 8 character salt and 22 character hash.
-
crypt.
METHOD_CRYPT
¶ 传统的方法,具备 2 个字符的 salt 和 13 个字符的哈希算法。这是最弱的方法。
35.5.3. 模块函数¶
crypt
模块定义了以下函数:
-
crypt.
crypt
(word, salt=None)¶ word 通常是用户在提示符或图形界面上输入的口令。可选参数 salt 要么是
mksalt()
返回的字符串,即crypt.METHOD_*
之一(尽管不是所有平台都可用),要么就是一个完全加密的包含 salt 值的口令,正如本函数的返回值。如果未给出 salt,将使用最强的哈希方法(methods()
返回)。查验口令通常是传入纯文本密码 word ,和之前
crypt()
调用的结果进行比较,应该与本次调用的结果相同。salt (随机的 2 或 16 个字符的字符串,可能带有
$digit{TX-PL-LABEL}#x60;
前缀以提示相关方法) 将被用来扰乱加密算法。 salt 中的字符必须在[./a-zA-Z0-9]
集合中,但 Modular Crypt Format 除外,它会带有$digit{TX-PL-LABEL}#x60;
前缀。返回哈希后的口令字符串,将由 salt 所在字母表中的字符组成。
由于有些 crypt(3) 扩展允许不同的值, salt 大小也可不同,建议在查验口令时采用完整的加密后口令作为 salt。
3.3 版更變: 除了字符串之外, salt 还可接受
crypt.METHOD_*
值。
-
crypt.
mksalt
(method=None)¶ 返回用指定方法随机生成的 salt。如果没有给出 method,则使用
methods()
返回的最强方法。The return value is a string either of 2 characters in length for
crypt.METHOD_CRYPT
, or 19 characters starting with$digit$
and 16 random characters from the set[./a-zA-Z0-9]
, suitable for passing as the salt argument tocrypt()
.3.3 版新加入.
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")