15.1. hashlib — 安全哈希与消息摘要

源码: Lib/hashlib.py


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

注解

如果你想找到 adler32 或 crc32 哈希函数,它们在 zlib 模块中。

警告

有些算法已知存在哈希碰撞弱点,请参考最后的“另请参阅”段。

15.1.1. 哈希算法

There is one constructor method named for each type of hash. All return a hash object with the same simple interface. For example: use sha1() to create a SHA1 hash object. You can now feed this object with bytes-like objects (normally bytes) using the update() method. At any point you can ask it for the digest of the concatenation of the data fed to it so far using the digest() or hexdigest() methods.

注解

为了更好的多线程性能,在对象创建或者更新时,若数据大于2047字节则 Python 的 GIL 会被释放。

注解

update() 输入字符串对象是不被支持的,因为哈希基于字节而非字符。

Constructors for hash algorithms that are always present in this module are md5(), sha1(), sha224(), sha256(), sha384(), and sha512(). Additional algorithms may also be available depending upon the OpenSSL library that Python uses on your platform.

例如,如果想获取字节串 b'Nobody inspects the spammish repetition' 的摘要:

>>> import hashlib
>>> m = hashlib.md5()
>>> m.update(b"Nobody inspects")
>>> m.update(b" the spammish repetition")
>>> m.digest()
b'\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(b"Nobody inspects the spammish repetition").hexdigest()
'a4337bc45a8fc544c03f52dc550cd6e1e87021bc896588bd79e901e2'
hashlib.new(name[, data])

Is a generic constructor that takes the string name of the desired algorithm as its first parameter. It also exists to allow access to the above listed hashes as well as any other algorithms that your OpenSSL library may offer. The named constructors are much faster than new() and should be preferred.

使用 new() 并附带由 OpenSSL 所提供了算法:

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

Hashlib 提供下列常量属性:

hashlib.algorithms_guaranteed

A set containing the names of the hash algorithms guaranteed to be supported by this module on all platforms.

3.2 新版功能.

hashlib.algorithms_available

一个集合,其中包含在所运行的 Python 解释器上可用的哈希算法的名称。 将这些名称传给 new() 时将可被识别。 algorithms_guaranteed 将总是它的一个子集。 同样的算法在此集合中可能以不同的名称出现多次(这是 OpenSSL 的原因)。

3.2 新版功能.

下列值会以构造器所返回的哈希对象的常量属性的形式被提供:

hash.digest_size

以字节表示的结果哈希对象的大小。

hash.block_size

以字节表示的哈希算法的内部块大小。

hash 对象具有以下属性:

hash.name

此哈希对象的规范名称,总是为小写形式并且总是可以作为 new() 的形参用来创建另一个此类型的哈希对象。

在 3.4 版更改: 该属性名称自被引入起即存在于 CPython 中,但在 Python 3.4 之前并未正式指明,因此可能不存在于某些平台上。

哈希对象具有下列方法:

hash.update(arg)

Update the hash object with the object arg, which must be interpretable as a buffer of bytes. Repeated calls are equivalent to a single call with the concatenation of all the arguments: m.update(a); m.update(b) is equivalent to m.update(a+b).

在 3.1 版更改: 当使用 OpenSSL 提供的哈希算法在大于 2047 字节的数据上执行哈希更新时 Python GIL 会被释放以允许其他线程运行。

hash.digest()

返回当前已传给 update() 方法的数据摘要。 这是一个大小为 digest_size 的字节串对象,字节串中可包含 0 至 255 的完整取值范围。

hash.hexdigest()

类似于 digest() 但摘要会以两倍长度字符串对象的形式返回,其中仅包含十六进制数码。 这可以被用于在电子邮件或其他非二进制环境中安全地交换数据值。

hash.copy()

返回哈希对象的副本(“克隆”)。 这可被用来高效地计算共享相同初始子串的数据的摘要。

15.1.2. 密钥派生

密钥派生和密钥延展算法被设计用于安全密码哈希。 sha1(password) 这样的简单算法无法防御暴力攻击。 好的密码哈希函数必须可以微调、放慢步调,并且包含 加盐

hashlib.pbkdf2_hmac(hash_name, password, salt, iterations, dklen=None)

此函数提供 PKCS#5 基于密码的密钥派生函数 2。 它使用 HMAC 作为伪随机函数。

字符串 hash_name 是要求用于 HMAC 的哈希摘要算法的名称,例如 ‘sha1’ 或 ‘sha256’。 passwordsalt 会以字节串缓冲区的形式被解析。 应用和库应当将 password 限制在合理长度 (例如 1024)。 salt 应当为适当来源例如 os.urandom() 的大约 16 个或更多的字节串数据。

iterations 数值应当基于哈希算法和算力来选择。 在 2013 年时,建议至少为 100,000 次 SHA-256 迭代。

dklen 为派生密钥的长度。 如果 dklenNone 则会使用哈希算法 hash_name 的摘要大小,例如 SHA-512 为 64。

>>> import hashlib, binascii
>>> dk = hashlib.pbkdf2_hmac('sha256', b'password', b'salt', 100000)
>>> binascii.hexlify(dk)
b'0394a2ede332c9a13eb82e9b24631604c31df978b4e2f0fbd2c549944f9d79a5'

3.4 新版功能.

注解

随同 OpenSSL 提供了一个快速的 pbkdf2_hmac 实现。 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
包含关于哪些算法存在已知问题以及对其使用所造成的影响的信息的 Wikipedia 文章。
https://www.ietf.org/rfc/rfc2898.txt
PKCS #5: 基于密码的加密规范描述 2.0 版