crypt —— 验证 Unix 口令的函数

源代码: Lib/struct.py

3.11 版后已移除: The crypt module is deprecated (see PEP 594 for details and alternatives). The hashlib module is a potential replacement for certain use cases.


本模块实现了连接 crypt(3) 的接口,是一个基于改进 DES 算法的单向散列函数;更多细节请参阅 Unix man 手册。可能的用途包括保存经过哈希的口令,这样就可以在不存储实际口令的情况下对其进行验证,或者尝试用字典来破解 Unix 口令。

请注意,本模块的执行取决于当前系统中 crypt(3) 的实际实现。 因此,当前实现版本可用的扩展均可在本模块使用。

可用性 :Unix。在 VxWorks 中不可用。

哈希方法

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 will usually be a user's password as typed at a prompt or in a graphical interface. The optional salt is either a string as returned from mksalt(), one of the crypt.METHOD_* values (though not all may be available on all platforms), or a full encrypted password including salt, as returned by this function. If salt is not provided, the strongest method available in methods will be used.

查验口令通常是传入纯文本密码 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)

Return a randomly generated salt of the specified method. If no method is given, the strongest method available in methods is used.

返回一个字符串,可用作传入 crypt()salt 参数。

rounds 指定了 METHOD_SHA256, METHOD_SHA512METHOD_BLOWFISH 的循环次数。 对于 METHOD_SHA256METHOD_SHA512 而言,必须为介于 1000999_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")