14.1. hashlib — 安全哈希和消息摘要 — Python 文档
14.1. 哈希库 — 安全散列和消息摘要
2.5 版中的新功能。
该模块为许多不同的安全散列和消息摘要算法实现了一个通用接口。 包括 FIPS 安全哈希算法 SHA1、SHA224、SHA256、SHA384 和 SHA512(在 FIPS 180-2 中定义)以及 RSA 的 MD5 算法(在 Internet RFC 1321中定义) . 安全散列和消息摘要这两个术语可以互换。 较旧的算法称为消息摘要。 现代术语是安全哈希。
警告
一些算法已知散列冲突的弱点,请参阅最后的“另请参阅”部分。
每种类型的 hash 都有一个构造函数方法。 都返回一个具有相同简单接口的哈希对象。 例如:使用 sha1()
创建一个 SHA1 哈希对象。 您现在可以使用 update()
方法为该对象提供任意字符串。 在任何时候,您都可以使用 digest()
或 hexdigest()
方法要求它提供迄今为止馈送给它的字符串串联的 digest。
该模块中始终存在的哈希算法的构造函数是 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
更浓缩:
>>> 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
提供此模块保证支持的哈希算法名称的元组。
2.7 版中的新功能。
- hashlib.algorithms_guaranteed
包含保证在所有平台上由该模块支持的哈希算法名称的集合。
2.7.9 版中的新功能。
- hashlib.algorithms_available
包含正在运行的 Python 解释器中可用的哈希算法名称的集合。 这些名称在传递给 new() 时将被识别。 algorithms_guaranteed 将始终是一个子集。 相同的算法可能会以不同的名称多次出现在该集合中(感谢 OpenSSL)。
2.7.9 版中的新功能。
以下值作为构造函数返回的散列对象的常量属性提供:
- 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)
该函数提供了基于PKCS#5密码的密钥推导函数2。 它使用 HMAC 作为伪随机函数。
字符串 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 版中的新功能。
笔记
pbkdf2_hmac 的快速实现可用于 OpenSSL。 Python 实现使用 hmac 的内联版本。 它大约慢了三倍,并且不会释放 GIL。
也可以看看
- 模块 hmac
- 使用哈希生成消息身份验证代码的模块。
- 模块 base64
- 另一种为非二进制环境编码二进制哈希的方法。
- http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
- 关于安全哈希算法的 FIPS 180-2 出版物。
- https://en.wikipedia.org/wiki/Cryptographic_hash_function#Cryptographic_hash_algorithms
- 维基百科文章,其中包含有关哪些算法存在已知问题以及它们的使用意味着什么的信息。