Python——hashlib
该模块实现了诸多安全哈希和消息摘要算法的通用接口,包括 FIPS 安全哈希算法: SHA1, SHA224, SHA256, SHA384 和 SHA512 算法(在 FIPS 180-2 中定义),还有 RSA 的 MD5 算法(在 RFC 1321 中定义)。“安全哈希” 和 “消息摘要” 是等价的,旧的算法被称为消息摘要,新的术语则称其为安全哈希。
* adler32 和 crc32 算法在 zlib 模块中。
* 某些算法存在已知的哈希冲突漏洞,请参考“六、另见”。
目录
每一类哈希算法对应一个构造器,调用这些构造器会返回具有相同接口的 hash 对象。
该模块一定支持的构造器或哈希算法有: md5(),sha1(),sha224(),sha256(),sha384() 和 sha512(),其他的算法则要看 Python 在你的平台上依赖的 OpenSSL 库的支持情况。
如调用 hashlib.sha1() 来创建一个基于 SHA1 算法的 hash 对象,然后就可以用 update() 方法为其填充任意的字符串。在任意时刻都可以用 digest() 或 hexdigest() 对这个对象中已有字符串的连接求摘要。
例如:
获取'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() 构造器也可以用来生成 hash 对象,这个构造器的第一个参数是算法的名称,这时的作用等同于具体算法对应的专用构造器。不过特定算法专用的构造器更快,应该优先使用它们。
例如:
>>> h = hashlib.new('ripemd160') >>> h.update("Nobody inspects the spammish repetition") >>> h.hexdigest() 'cc4a5ce1b3df48aec5d22d1f16b894a0b894eccc'
- hashlib.algorithms
- 一个列明该模块所支持的算法名称的元组,Python 2.7 引入。
- hashlib.algorithms_guaranteed
- 一个包含该模块跨所有平台都支持的算法名称的集合,Python 2.7.9 引入。
- hashlib.algorithms_available
- 一个集合,包含当前Python解释器支持的哈希算法名称,该集合中的名称传入 new() 时永远合法。algorithms_guaranteed 是这个属性的子集,同一个算法可能会在这个集合中以不同的名称出现多次(多亏了OpenSSL),Python 2.7.9 引入。
- 三、hash 对象的属性
- hash.digest_size
- 结果哈希的长度(字节)
- hash.block_size
- 哈希算法的内部块的长度(字节)
- 四、hash 对象的方法
- hash.update(arg)
- 用字符串参数更新 hash 对象,多次调用等于将参数连接起来调用该函数,即:m.update(a);m.update(b) 等价于 m.update(a+b)。
- Python 2.7 中的改变:The Python GIL is released to allow other threads to run while hash updates on data larger than 2048 bytes is taking place when using hash algorithms supplied by OpenSSL.
- hash.digest()
- 返回所有使用 update()方法传入的字符串的连接的摘要。长度为digest_size,可能会包含非ASCII字符,包括 null 字节。
- hash.hexdigest()
- 返回结果的长度是 digest() 方法结果的两倍,只含16进制数值,以 ASCII 字符表示,可以用在非二进制的环境中。
- hash.copy()
- 返回 hash 对象的拷贝,可以有效地计算某些具有相同子串的字符串的摘要。
- 五、密钥导出函数
- 密钥导出(Key derivation)和密钥拉伸(key stretching)算法旨在保护密码哈希。普通的算法比如 sha1(password) 经不起暴力破解攻击,一个好的哈希算法必须是可调的,包括撒盐(salt)等。
- hashlib.pbkdf2_hmac(name, password, salt, rounds, dklen=None)
- 该函数提供 PKCS#5 基于密码的密钥导出函数,且采用 HMAC 作为伪随机函数。
- 参数 name 是 HMAC 要用到的哈希摘要算法,例如:‘sha1’ 或 ‘sha256’。
- password 和 salt 被视为字节串,应用应该将 password 限制为一个合理的长度 (如:1024)。 salt 应该大约 16 或更多个 bytes,且拥有可靠的来源(如:os.urandom())
- 参数 rounds 应基于算法和计算能力设置,比如 100,000 轮 SHA-256 是推荐的次数。
- 参数 dklen 是导出的密钥的长度。如果 dklen 是 None 那么就用参数 name 指定的哈希算法的摘要长度,比如SHA-512为64。
- Python 2.7.8 引入
>>> import hashlib, binascii >>> dk = hashlib.pbkdf2_hmac('sha256', b'password', b'salt', 100000) >>> binascii.hexlify(dk) b'0394a2ede332c9a13eb82e9b24631604c31df978b4e2f0fbd2c549944f9d79a5'
*注意:
pbkdf2_hmac 的一个快速实现版本可以使用OpenSSL, Python 的实现使用了行内的 hmac 版本。这样更慢,耗时大概是前者的三倍,不会释放GIL。