14.1. hashlib —安全哈希和消息摘要

2.5 版的新Function。

源代码: Lib/hashlib.py


该模块为许多不同的安全哈希和消息摘要算法实现了一个通用接口。包括 FIPS 安全哈希算法 SHA1,SHA224,SHA256,SHA384 和 SHA512(在 FIPS 180-2 中定义),以及 RSA 的 MD5 算法(在 Internet RFC 1321中定义)。术语安全哈希和消息摘要是可以互换的。较旧的算法称为消息摘要。现代术语是安全哈希。

Note

如果要使用 adler32 或 crc32 哈希函数,可以在zlib模块中使用它们。

Warning

一些算法具有哈希冲突弱点,请参阅最后的“另请参见”部分。

每种* hash *类型都有一个构造函数方法。全部返回具有相同简单接口的哈希对象。例如:使用sha1()创建 SHA1 哈希对象。现在,您可以使用update()方法为该对象提供任意字符串。在任何时候,您都可以使用digest()hexdigest()方法向它索取馈送给它的字符串的“摘要”。

此模块中始终存在的哈希算法构造函数为md5()sha1()sha224()sha256()sha384()sha512()。取决于 Python 在平台上使用的 OpenSSL 库,还可以使用其他算法。

例如,要获取字符串'Nobody inspects the spammish repetition'的摘要:

>>> import hashlib
>>> m = hashlib.md5()
>>> m.update("Nobody inspects")
>>> m.update(" the spammish repetition")
>>> m.digest()
'\xbbd\x9c\x83\xdd\x1e\xa5\xc9\xd9\xde\xc9\xa1\x8d\xf0\xff\xe9'
>>> m.digest_size
16
>>> m.block_size
64

More condensed:

>>> hashlib.sha224("Nobody inspects the spammish repetition").hexdigest()
'a4337bc45a8fc544c03f52dc550cd6e1e87021bc896588bd79e901e2'

还存在一个通用的new()构造函数,该构造函数将所需算法的字符串名称作为其第一个参数,以允许访问上面列出的哈希以及 OpenSSL 库可能提供的任何其他算法。命名的构造函数比new()快得多,应该首选。

new()与 OpenSSL 提供的算法结合使用:

>>> h = hashlib.new('ripemd160')
>>> h.update("Nobody inspects the spammish repetition")
>>> h.hexdigest()
'cc4a5ce1b3df48aec5d22d1f16b894a0b894eccc'

该模块提供以下常量属性:

  • hashlib. algorithms
    • 提供保证由该模块支持的哈希算法名称的 Tuples。

2.7 版的新Function。

  • hashlib. algorithms_guaranteed
    • 包含哈希算法名称的集合,保证该模块在所有平台上均受支持。

2.7.9 版中的新Function。

  • hashlib. algorithms_available
    • 一组包含正在运行的 Python 解释器中可用的哈希算法的名称。这些名称将在传递给new()时被识别。 algorithms_guaranteed将始终是子集。同一算法在此集中可能以不同的名称多次出现(这要感谢 OpenSSL)。

2.7.9 版中的新Function。

提供以下值作为构造函数返回的哈希对象的常量属性:

  • hash. digest_size

    • 所得哈希的大小(以字节为单位)。
  • hash. block_size

    • 哈希算法的内部块大小(以字节为单位)。

哈希对象具有以下方法:

  • hash. update(* arg *)
    • 用字符串* arg *更新哈希对象。重复调用等效于将所有参数串联在一起的单个调用:m.update(a); m.update(b)等效于m.update(a+b)

在版本 2.7 中进行了更改:发布了 Python GIL,以允许其他线程运行,同时使用 OpenSSL 提供的哈希算法对大于 2048 字节的数据进行哈希更新。

  • hash. digest ( )

    • 返回到目前为止传递给update()方法的字符串的摘要。这是一个digest_size个字节的字符串,其中可能包含非 ASCII 字符,包括空字节。
  • hash. hexdigest ( )

    • digest()一样,摘要以双倍长度的字符串返回,仅包含十六进制数字。这可用于在电子邮件或其他非二进制环境中安全地交换值。
  • hash. copy ( )

    • 返回哈希对象的副本(“克隆”)。这可用于有效地计算共享公共初始子字符串的字符串的摘要。

14.1.1. 密钥派生

密钥派生和密钥扩展算法设计用于安全密码哈希。天真的算法(例如sha1(password))不能抵抗暴力攻击。好的密码哈希函数必须是可调的,缓慢的,并且必须包含salt

  • hashlib. pbkdf2_hmac(* name password salt rounds * * dklen = None *)
    • 该Function提供了基于 PKCS#5 密码的密钥派生Function 2.它使用 HMAC 作为伪随机Function。

字符串* name *是 HMAC 的哈希摘要算法的所需名称,例如'sha1'或'sha256'。 * password salt 被解释为字节缓冲区。应用程序和库应将 password *限制为合理的值(例如 1024)。 * salt *应该是来自适当来源的大约 16 个或更多字节,例如os.urandom()

回合的数量应根据哈希算法和计算能力来选择。截至 2013 年,建议至少进行 100,000 轮 SHA-256.

  • dklen 是派生密钥的长度。如果 dklen None,则使用哈希算法 name *的摘要大小,例如 SHA-512 为 64.
>>> import hashlib, binascii
>>> dk = hashlib.pbkdf2_hmac('sha256', b'password', b'salt', 100000)
>>> binascii.hexlify(dk)
b'0394a2ede332c9a13eb82e9b24631604c31df978b4e2f0fbd2c549944f9d79a5'

2.7.8 版中的新Function。

Note

OpenSSL 提供了* pbkdf2_hmac *的快速实现。 Python 实现使用内联版本hmac。它慢了大约三倍,并且不会释放 GIL。

See also