跳转到主要内容

Python 3.13中删除的`crypt`模块的副本

项目描述

原作者:Steven D. Majewski <sdm7g@virginia.edu>

crypt_r模块是Python 3.12中现有的crypt模块的更名副本,在删除之前。

有关删除的详细信息,请参阅PEP 594

与crypt不同,此库始终暴露crypt_r(3)函数,而不是crypt(3)

请注意,crypt_r 不是任何标准的一部分。此库与 Fedora Linux 中 crypt_r 的实现(截至 2024 年为 libxcrypt)进行了测试,并且应该与兼容的 crypt_r 实现(如旧 glibc 中的 libcrypt.so)兼容。

请注意,crypt_r 相对于 crypt 的改进在于内存管理和线程安全,而非安全性/密码学。

使用 crypt_r 以不安全的方式很容易。值得注意的是:除了 METHOD_CRYPT(20世纪70年代原始 Unix 算法)之外的所有哈希方法都是可选的平台特定扩展。此库不公开像 libxcrypt 的 yescrypt 这样的现代哈希方法。最后的包装更新是在 2017 年。没有计划进行未来的开发。

要使用此模块,您可以选择显式导入 crypt_r 或使用旧的 crypt 名称以实现向后兼容性。然而,在 Python 3.13 之前的版本中,标准库中的 crypt 模块通常会在 sys.path 中优先于 crypt_r

以下是对已删除的 crypt 模块的原始文档,已更新为引用 crypt_r


此模块实现了对 crypt_r(3) 例程的接口,这是一个基于修改后的 DES 算法的单向哈希函数;有关详细信息,请参阅 Unix man 页。可能的用途包括存储哈希密码,以便您可以在不存储实际密码的情况下检查密码,或使用字典尝试破解 Unix 密码。

请注意,此模块的行为取决于运行系统中 crypt_r(3) 例程的实际实现。因此,当前实现上可用的任何扩展也将在此模块上可用。

哈希方法

Python 3.3 中的新功能。

crypt_r 模块定义了哈希方法列表(并非所有方法都在所有平台上可用)

METHOD_SHA512

基于 SHA-512 哈希函数的 16 字符盐和 86 字符哈希的模块加密格式方法。这是最强的方法。

METHOD_SHA256

基于 SHA-256 哈希函数的 16 字符盐和 43 字符哈希的另一种模块加密格式方法。

METHOD_BLOWFISH

基于 Blowfish 加密算法的 22 字符盐和 31 字符哈希的另一种模块加密格式方法。

Python 3.7 中的新功能。

METHOD_MD5

基于 MD5 哈希函数的 8 字符盐和 22 字符哈希的另一种模块加密格式方法。

METHOD_CRYPT

带有 2 个字符盐和 13 个字符哈希的传统方法。这是最弱的方法。

模块属性

Python 3.3 中的新功能。

methods

一个可用密码哈希算法列表,作为 crypt.METHOD_* 对象。此列表按最强到最弱排序。

模块函数

crypt_r 模块定义了以下函数

crypt(word, salt=None)

word 通常是一个用户在提示或图形界面中输入的密码。可选的 saltmksalt() 返回的字符串、crypt.METHOD_* 的值之一(尽管并非所有平台都可用),或包含盐的完整加密密码,如此函数返回。如果未提供 salt,则将使用 methods 中可用的最强方法。

检查密码通常是通过将明文密码作为 word 和先前 crypt 调用的完整结果(应与此次调用的结果相同)传递来完成的。

(可以是随机生成的2或16位字符串,可能以digit开头表示方法),将用于扰动加密算法。盐中的字符必须是集合[./a-zA-Z0-9]中的字符,除了模数加密格式,其前缀为digit

返回作为字符串的哈希密码,该字符串将由与盐相同的字母表中的字符组成。

由于一些crypt_r(3)扩展允许不同的值,盐的大小不同,建议在检查密码时使用完整的加密密码作为盐。

在Python 3.3中更改:除了字符串外,还接受crypt.METHOD_*的值作为

mksalt(method=None, *, rounds=None)

返回指定方法的随机生成的盐。如果没有提供method,则使用methods中可用的最强方法。

返回值是一个字符串,适合作为crypt参数传递。

rounds指定METHOD_SHA256METHOD_SHA512METHOD_BLOWFISH的轮数。对于METHOD_SHA256METHOD_SHA512,它必须是介于1000999_999_999之间的整数,默认值为5000。对于METHOD_BLOWFISH,它必须是介于16(24)和2_147_483_648(231)之间的2的幂,默认值为4096(212)。

Python 3.3 中的新功能。

在Python 3.7中更改:添加了rounds参数。

示例

一个简单的示例,说明典型用法(需要常数时间比较操作来限制对时间攻击的暴露。《hmac.compare_digest()》适用于此目的)

import pwd
import crypt_r
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_r.crypt(cleartext, cryptedpasswd), cryptedpasswd)
    else:
        return True

使用最强可用方法生成密码的哈希并检查其与原始密码是否匹配

import crypt_r
from hmac import compare_digest as compare_hash

hashed = crypt_r.crypt(plaintext)
if not compare_hash(hashed, crypt_r.crypt(plaintext, hashed)):
    raise ValueError("hashed version doesn't validate against original")

变更日志

3.13.1

  • 修复使用-Werror=incompatible-pointer-types构建的问题

3.13.0

  • 从CPython 3.12.3开始分叉

  • 始终使用crypt_r(3)函数,而不是crypt(3)

  • 将Python模块重命名为crypt_r_crypt_r

有关此模块包含在Python中的历史变更,请参阅Python 3.12 变更日志

由以下支持