python模塊之hashlib
摘要算法
1. 摘要算法又稱為哈希算法、散列算法,是通過函數將任意長度的數據轉化成固定長度的數據串(通常用16進制的字符串表示)。
2. 摘要算法將通過摘要函數f()將數據轉化成固定長度的摘要(digest),目的是判斷原始數據是否被別人修改過
3. 能夠判斷的原因是摘要函數是單向函數,計算data很容易,通過digest反推data很難,而且對原始數據做一個bit的修改都會導致計算出的摘要完全不同
常見的摘要算法有MD5,SHA1等
1 import hashlib 2 s1 = "life is short, carpe diem!" 3 ret = hashlib.md5() 4 ret.update(s1.encode("utf-8")) 5 print(ret.hexdigest()) # 7eda5bd766debaf18e333c949f250580
輸入數據量大,可以分塊多次調用update()
ret = hashlib.md5() with open("test", encoding="utf-8", mode="r") as f1: for line in f1: ret.update(line.encode("utf-8")) print(ret.hexdigest()) # 271d9daa363f2ab8a48c0d0ecd339dd3
MD5是常見的摘要算法,生成速度快,生成結果是一個128bit的數字,通常用32個16進制位表示。SHA1與MD5的用法類似
s1 = "life is short, seize the day!" ret = hashlib.sha1() ret.update(s1.encode("utf-8")) print(ret.hexdigest()) # bd60da31ae2b9f407d019ff61bdbc237925ab664
SHA1的生成結果是160bit,用40個16進制表示,比SHA1更安全的算法是SHA256, SHA512,它們生成的結果更長,速度也更慢
摘要算法應用
1. 保存用戶名和口令
如果以明文存儲密碼的話,那麽數據庫泄露,所有的用戶口令就會落到黑客手中,此外,運維人員也是可以訪問數據庫的,也能獲取到用戶的口令,所以正確的方式應該是存儲密文。
簡化版
password = "123456" ret = hashlib.md5() ret.update(password.encode("utf-8")) print(ret.hexdigest()) # e10adc3949ba59abbe56e057f20f883e
上述口令比較簡單,因此可以把常用的口令如123,888等對應的MD5值計算出來,得到反推表,然後通過反推表去破解密碼(撞庫),怎麽防止呢?加鹽!原始口令加一個復雜的字符串來MD5,這個復雜的字符串就稱為"鹽"
加鹽版
password = "123456" ret = hashlib.md5("hello".encode("utf-8")) # "hello"就是鹽 ret.update(password.encode("utf-8")) print(ret.hexdigest()) # eeb9bad681184779aa6570e402d6ef6c
經過加鹽的口令,只要不是鹽被黑客知道,就很難破解。但是如果兩個用戶的口令相同,那麽它們的MD5也會是相同的,有沒有一種方法使不同的用戶生成不同的MD5呢,?有的,我們可以把用戶名設置成鹽,不同的用戶名作為鹽,這就是動態加鹽
動態加鹽版
name = input(">>>") password = input(">>>") ret = hashlib.md5(name[::2].encode("utf-8")) ret.update(password.encode("utf-8")) print(ret.hexdigest())
輸入不同的用戶名(密碼相同)
>>>Robin >>>123456 0acbae48d9e086089d52d54392365a04 >>>Rose >>>123456 825f3023698149b539a17a0f74753eeb # MD5不同
2. 文件校驗
文件在傳輸過程中可能發生損壞,因此需要進行文件校驗。我們先創建兩個相同的文件test1和test2。文件內容:
臨江仙 夜飲東坡醒復醉 歸來仿佛三更 家童鼻息已雷鳴 敲門都不應 倚仗聽江聲 長恨此生非我有 何時忘卻營營 夜闌風靜縠紋平 小舟從此逝 江海寄余生
1 def file_veri(file): 2 with open(file, encoding="utf-8", mode="r") as f: 3 while True: 4 content = f.read(1024) 5 if not content: 6 break 7 ret = hashlib.md5() 8 ret.update(content.encode("utf-8")) 9 return ret.hexdigest() 10 11 12 print(file_veri("test1")) # 4b852fe14346408bdc7c1ab6603b03fe 13 print(file_veri("test2")) # 4b852fe14346408bdc7c1ab6603b03fe
註意摘要算法不是加密算法,不能用於加密,因為無法通過摘要反推明文,只能用於防篡改,但是它的單向計算特性決定了可以在不存儲明文口令的情況下驗證用戶口令。
python模塊之hashlib