python hashlib模塊簡介
一、hashlib模塊里有什么
hashlib模塊提供了多種安全散列和消息摘要算法的公共接口。
校驗和算法adler32或crc32則在zlib模塊中提供。[1]
在hashlib模塊中,sha1()、sha224()、sha256()、sha384()、sha512()和blake2b()、blake2s()方法總是存在的。
md5()方法通常也是可用的。如果使用了罕見的兼容美國聯(lián)邦信息處理標(biāo)準(zhǔn)(FIPS compliant)的python,則md5()可能會不能用(MD5的安全性不夠高的原因)。
其它算法是否可用依賴于python所在操作系統(tǒng)的OpenSSL庫。在大多數(shù)操作系統(tǒng)中,sha3_224()、sha3_256()、sha3_384()、sha3_512()和shake_128()、shake_256()是可用的。
具體哪些散列算法能用,可以用下面的常量來查看。
使用前先導(dǎo)入:
import hashlib
可以使用常量:
hashlib.algorithms_available 或 hashlib.algorithms_guaranteed來獲取本模塊支持的散列算法集合。
hashlib.algorithms_available
返回可用的散列函數(shù)名集合。包含了sha384,sha521,md5等32個散列函數(shù)。
注意,相同的函數(shù)可能會以不同名字(大小寫)出現(xiàn)多次。
{'RIPEMD160', 'sha224', 'sha3_224', 'SHA384', 'blake2s', 'blake2b',
'sha3_512', 'sha1', 'DSA', 'ripemd160', 'sha3_384', 'sha3_256',
'sha', 'shake_128', 'sha512', 'ecdsa-with-SHA1', 'shake_256',
'SHA', 'SHA512', 'dsaEncryption', 'MD5', 'SHA256', 'DSA-SHA',
'whirlpool', 'MD4', 'dsaWithSHA', 'SHA224', 'sha256', 'md4',
'sha384', 'md5', 'SHA1'}
hashlib.algorithms_guaranteed
返回本模塊支持的散列函數(shù)名集合。包含了sha3_256、md5等14個散列函數(shù)。此時沒有大小寫問題了。
algorithms_guaranteed返回結(jié)果是 algorithms_available返回結(jié)果的子集。
{'shake_256', 'sha224', 'sha3_224', 'blake2s', 'blake2b',
'sha3_512', 'sha1', 'shake_128', 'sha3_384', 'sha256',
'sha3_256', 'sha384', 'md5', 'sha512'}
二、散列算法的應(yīng)用場景
這些散列函數(shù)經(jīng)常應(yīng)用于一致性驗證、數(shù)字簽名、安全訪問認(rèn)證等場合。[2]
比如用MD5(信息摘要算法第5版)進(jìn)行文件一致性驗證。
每個文件的MD5值就像是這個文件的“數(shù)字指紋”。如果任何人對文件做了任何改動,其MD5值也就是對應(yīng)的“數(shù)字指紋”就會發(fā)生變化。
在軟件下載操作中,通過比較前后這兩個MD5值是否相同,就能判斷下載的文件是否出錯,或者說下載的文件是否被篡改了。

三、使用示例
blake2b
blake2s
md5
sha1
sha224
sha256
sha384
sha512
sha3_224
sha3_256
sha3_384
sha3_512
shake_128
shake_256
這些散列算法的使用方式都是相同的,因為它們返回的都是具有相同接口的散列對象。
比如使用sha256()方法創(chuàng)建SHA-256散列對象,用字節(jié)型數(shù)據(jù)當(dāng)參數(shù)調(diào)用update()方法,
用digest()或hexdigest()方法獲得相應(yīng)的摘要信息。
演示代碼如下:
#coding=utf-8
import hashlib
text = b'hello world.'
hs = hashlib.sha256()
hs.update(text)
out_text = hs.hexdigest()
print(text, '\n==> ', out_text)
# 內(nèi)容是中文時注意編碼轉(zhuǎn)換
msg = '代碼小工蟻'.encode('utf-8')
msg_hs = hashlib.sha256()
msg_hs.update(msg)
out_msg = msg_hs.hexdigest()
print(msg, '\n==> ', out_msg)
print(len(out_msg)) # 長度64位
注意:
1、update()方法的參數(shù)要是字節(jié)型,英文字符可以在字符串前加b來標(biāo)識,中文等非ASCII字符要進(jìn)行編碼轉(zhuǎn)換。
如:msg = '代碼小工蟻'.encode('utf-8')
msg = bytes('代碼小工蟻', encoding='utf-8')
2、對同一個hash對象進(jìn)行update()操作實(shí)際上相當(dāng)于參數(shù)拼接后的update()。
即hs.update(b'abc'),再來hs.update(b'def'),相當(dāng)于hs.update(b'abc' + b'def'),同hs.update(b'abcdef')
3、散列對象的hexdigest()方法返回字符型摘要信息(處理結(jié)果),digest()返回的是字節(jié)型的摘要信息。
百度翻譯API的代碼片斷:
# 申請API地址:
# http://api.fanyi.baidu.com/api/trans/product/index
appid = '2018***********78'
secretKey = 'Qw6n**************fW'
myurl = 'http://api.fanyi.baidu.com/api/trans/vip/translate'
q = trans_text
fromLang = 'en'
toLang = 'zh'
salt = random.randint(32768, 65536)
sign = appid+q+str(salt)+secretKey
m1 = hashlib.md5()
m1.update(sign.encode('utf-8'))
sign = m1.hexdigest()
myurl = myurl+'?appid='+appid+'&q='+quote(q)+'&from='+fromLang+'&to='+toLang+'&salt='+str(salt)+'&sign='+sign
代碼說明:
百度翻譯API使用的md5()方法。
salt = random.randint(32768, 65536)
使用隨機(jī)整數(shù)“加鹽”(增加額外的信息,提高復(fù)雜度,使信息摘要更有隱蔽性)
四、存在問題及發(fā)展
SHA-1存在嚴(yán)重的安全問題。2017年2月份,CWI Amsterdam和Google宣布實(shí)現(xiàn)對SHA-1碰撞攻擊。
(總計約900萬兆次SHA1計算。完成攻擊的首個階段需要單一CPU計算6500年。)[3]
SHA-2家族包括:SHA-256、SHA-384和SHA-512以及SHA-224。
SHA-3競賽獲勝算法Keccak算法成為SHA-3,也是一個哈希家族。
BLAKE2的定位是目前安全系數(shù)最高的哈希函數(shù)。其中:
BLAKE2b是BLAKE的64位版本,它可以生成最高512位的任意長度哈希。
BLAKE2s是BLAKE的32位版本,它可以生成最高256位的任意長度哈希。
BLAKE2的速度比MD5、SHA-1要快。[4]

有人說,只需要一個智能手機(jī)30秒就能破解md5。[3]
我嘗試了一下,8位0-9純數(shù)字的MD5暴力破解花了約140秒。
看來程序還要優(yōu)化。
* 所有示例在WIN7 64位系統(tǒng)上執(zhí)行python3.6.1通過。
[1]hashlib (python 3.6)官方文檔:
https://docs.python.org/3.6/library/hashlib.html#hash-algorithms
[2]百度百科:MD5、SHA家族
[3]SHA-1被破解始末
https://mp.weixin.qq.com/s/ND9zg3YJmi13OHN28hP5QQ
[4]BLAKE2簡介
https://blog.csdn.net/u010129119/article/details/79105208