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

2.5 版中新增。

源程序代码:Lib/hashlib.py


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

如果你想要 adler32 或 crc32 哈希函数,它们位于zlib模块中。

警告

一些算法具有已知的哈希冲突弱点,请参阅末尾的"另请参见"一节。

每种类型的湊雜都具有一个命名构造函数。它们都返回一个具有相同的简单接口的哈希对象。例如:使用sha1()来创建一个 SHA1 哈希对象。现在你可以使用update()方法来对这个对象填充任意的字符串。在任何时候你都可以使用digest()hexdigest()方法问它要目前为止填充的字符串的摘要

本模块中总是存在的哈希算法的构造函数有md5()sha1()sha224()sha256()sha384()sha512()可能还有其它算法,这取决于在你的平台上Python 使用的 OpenSSL 库。

例如,若要获取字符串'Nobody inpects 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()快得多,应该优先选择命名的构造函数。

使用OpenSSL 提供的一个算法调用new()

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

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

hashlib.algorithms

一个元组,提供该模块保证支持的哈希算法的名称。

2.7 版中新增。

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

hash.digest_size

以字节为单位的哈希结果的大小。

hash.block_size

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

哈希对象都具有以下方法:

hash.update(arg)

用字符串arg更新哈希对象。重复的调用等同于单次调用所有参数的连接:m.update(a); m.update(b) 相当于m.update(a+b)

2.7 版本中的更改:当使用OpenSSL 提供的哈希算法时,如果哈希正在更新大于2048 字节的数据,将释放Python GIL 以允许其它线程运行。

hash.digest()

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

hash.hexdigest()

类似digest(),但是返回的摘要的字符串的长度翻倍,且只包含十六进制数字。这可用于在电子邮件或其它非二进制环境中安全交换数据。

hash.copy()

返回哈希对象的一个副本("克隆")。这可以用于更有效地计算分享一个共同的初始子字符串的字符串的摘要。

14.1.1. 密钥派生函数

密钥派生和密钥stretching 设计用于安全的密码哈希。朴素的算法如sha1(password)不耐蛮力攻击。一个好的密码哈希函数必须是可调谐、 速度慢,并且包括一个salt

hashlib.pbkdf2_hmac(name, password, salt, rounds, dklen=None)

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

字符串name是HMAC 想要的哈希摘要算法的名称,例如 'sha1' 或 'sha256' 。passwordsalt被解释为缓冲区的字节数。应用程序和库应该限制password到一个合理的值(如 1024)。salt 应该是来自正确来源的16或更多个字节,例如os.urandom()

rounds数目的选择应基于哈希算法和计算能力。2013年起,建议SHA-256 的rounds 至少为 100,000。

dklen是派生密钥的长度。如果dklenNone ,则使用的哈希算法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 版中新增。

OpenSSL 中实现的pbkdf2_hmac 更加快速。这里Python 的实现使用自身版本hmac它慢了约三倍且不释放 GIL。

请参见

模块 hmac
使用哈希生成消息认证码的一个模块
模块 base64
用于非二进制环境的编码二进制哈希的另外一种方式
http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
关于安全哈希算法的 FIPS 180-2 的公开发行
http://en.wikipedia.org/wiki/Cryptographic_hash_function#Cryptographic_hash_algorithms
维基百科的文章,关于哪些算法有已知问题和使用中的含义