crypt —— 验证 Unix 口令的函数¶
源代码: Lib/struct.py
从 3.11 版起不建议使用,将在 3.13 版中移除: crypt 模块已被弃用(请参阅 PEP 594 了解详情及其替代品)。 hashlib 模块是针对特定应用场景的潜在替换物。 passlib 包可以替代此模块的所有应用场景。
本模块实现了连接 crypt(3) 的接口,是一个基于改进 DES 算法的单向散列函数;更多细节请参阅 Unix man 手册。可能的用途包括保存经过哈希的口令,这样就可以在不存储实际口令的情况下对其进行验证,或者尝试用字典来破解 Unix 口令。
请注意,本模块的执行取决于当前系统中 crypt(3) 的实际实现。 因此,当前实现版本可用的扩展均可在本模块使用。
可用性: Unix,不包括 VxWorks。
可用性: 非 Emscripten,非 WASI。
此模块在 WebAssembly 平台 wasm32-emscripten 和 wasm32-wasi 上不适用或不可用。 请参阅 WebAssembly 平台 了解详情。
哈希方法¶
在 3.3 版本加入.
crypt 模块定义了哈希方法的列表(不是所有的方法在所有平台上都可用)。
- crypt.METHOD_SHA512¶
- 基于 SHA-512 哈希函数的模块化加密格式方法,具备 16 个字符的 salt 和 86个字符的哈希算法。这是最强的哈希算法。 
- crypt.METHOD_SHA256¶
- 另一种基于 SHA-256 哈希函数的模块化加密格式方法,具备 16 个字符的 salt 和 43 个字符的哈希算法。 
- crypt.METHOD_BLOWFISH¶
- 另一种基于 Blowfish 的模块化加密格式方法,有 22 个字符的 salt 和 31 个字符的哈希算法。 - 在 3.7 版本加入. 
- crypt.METHOD_MD5¶
- 另一种基于 MD5 哈希函数的模块化加密格式方法,具备 8 个字符的 salt 和 22 个字符的哈希算法。 
- crypt.METHOD_CRYPT¶
- 传统的方法,具备 2 个字符的 salt 和 13 个字符的哈希算法。这是最弱的方法。 
模块属性¶
在 3.3 版本加入.
- crypt.methods¶
- 可用口令哈希算法的列表,形式为 - crypt.METHOD_*对象。该列表从最强到最弱进行排序。
模块函数¶
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, *, rounds=None)¶
- 返回用指定方法随机生成的 salt 值。 如果没有给出 method,则会使用 - methods中提供的最强方法。is used.- 返回一个字符串,可用作传入 - crypt()的 salt 参数。- rounds 指定了 - METHOD_SHA256,- METHOD_SHA512和- METHOD_BLOWFISH的循环次数。 对于- METHOD_SHA256和- METHOD_SHA512而言,必须为介于- 1000和- 999_999_999之间的整数,默认值为- 5000。 而对于- METHOD_BLOWFISH,则必须为- 16(24) 和- 2_147_483_648(231) 之间的二的幂,默认值为- 4096(212)。- 在 3.3 版本加入. - 在 3.7 版本发生变更: 加入 rounds 参数。 
例子¶
以下简单示例演示了典型用法(需要一个时间固定的比较操作来限制留给计时攻击的暴露面。 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")