hashlib的基本概述:
python中的 hashlib 模塊用來進行hash 或者md5加密,而且這種加密是不可逆的,所以這種算法又被稱為摘要算法,
其支持Opennssl庫提供的所有算法,包括 md5、sha1、sha224、sha256、sha512 等。
?
?
hash是一種算法 是將一個任意長的數據 根據計算 得到一個固定長度特征嗎
特征:1、不同輸入 ? 可能會有相同的結果 幾率特別小
2、相同的輸入 必然得到相同結果
3、由于散列(特征)的性質 從原理來看是不可能 反解
4、用來 驗證 ? 兩個輸入的數據是否一致
使用場景:
1、密碼驗證
2、驗證數據是否被篡改? 比如游戲安裝包 ?? 有沒有被改過
為了防止別人撞庫成功? 可用提升密碼的復雜度 ? 其次可以為密碼加鹽(加點內容進去)
ps:撞庫破解的原理? 把常見的 明文和密文的對應關系 存到了數據庫中? 運氣好就能查詢到
?
常用的屬性和方法:
algorithms : 列出所有加密算法
digesti——size: 產生的散列的字節大小
md5()/sha1() :創建一個 md5 或者 sha1加密模式的hash 對象
update(arg) :用字符串參數來更新hash對象,如果同一個has對象重復調用該方法,如下:m.update(a); m.update(b), 則等于m.update(a+b)
digest() : 返回摘要,作為二進制數據字符串值
hexdigest() : 返回摘要,作為十六進制數據字符串值
copy() :復制
?
下面是一個簡單的實例:
import hashlib m = hashlib.md5("aaa".encode("utf-8")) print(m.hexdigest())
結果如下:
47bce5c74f589f4867dbd57e9ca9f808
?
下面是一個簡單的加鹽實例:
import hashlibm = hashlib.md5("321".encode("utf-8")) #加 m.update("abcdefplkjoujhh".encode("utf-8"))print(m.hexdigest())
結果如下:
7da0befdd8fd811dd0716941c38c0111
?
關于hmac 的實例:
import hmac # 與hashlib 沒啥區別 只是在創建的時候必須加鹽 h = hmac.new("abcdefjjjj".encode("utf-8"))h.update("123".encode("utf-8"))print(h.hexdigest())
結果如下:
944b3523fac69f32f6d399a11707da8b
?
如何產生hash值的三個階段:
import hashlib # # ######## sha256 ######## # # 1、造出hash工廠 hash = hashlib.sha256('12345ds232'.encode('utf8')) #同一種hash算法得到的長度是固定的 # # 2、運送原材料 hash.update('alvin'.encode('utf8')) #工廠傳入的原材料都是bytes類型 # # 3、產出hash值 print(hash.hexdigest()) #結果:0f63932f6e2b2d1e0d9c2d50f0e9d39b79da78a5048a6d054d7f9c27d1a8761a
?
效驗文件的一致性(如何保證下載的文件過程中不丟包,保證數據的完整性!):
# -----------文件一致校驗---------------- '''可以拷貝一個文件放在兩個不同的盤中,然后通過判斷兩個文件的hash值是否相等,判斷兩個文件是否是同一個文件''' import hashlib m = hashlib.md5() with open(r'F:\oldboy課程記錄\目錄創建函數.py','rb') as f:for line in f:m.update(line) print(m.hexdigest()) #18b6754864943d03b5b2aedacb449466import hashlib m = hashlib.md5() with open(r'F:\oldboy課程記錄\購物車練習.py','rb') as f:for line in f:m.update(line) print(m.hexdigest()) #8e63f67a0049d1fc583a5c2bbf6cf3a8
?
對密碼進行加鹽(加密):
# 應用:對明文密碼進行加密(暴力破解-------用明文密碼用一種算法算出一個hash值,與截取的hash值進行比對,比對成功說明明文密碼一致,就可以破解用戶的密碼) '''如用戶在某網站進行注冊信息,這個時候防止信息被惡意攔截獲取,可以對用戶明文密碼進行加密,存成hash值得形式,這樣用戶每次登陸雖然輸的是明文密碼,校驗hash值即可''' #未加密 password=input('>>>>>:').strip() import hashlib m=hashlib.md5() m.update(password.encode('utf-8')) print(m.hexdigest()) #00dcbdaede875d5e23f1f9f64c7849ef# 對密碼進行加鹽(暗號)----------進一步加強密碼的安全性 password=input('>>>>>:').strip() import hashlib m=hashlib.md5() m.update('一行白鷺上青天'.encode('utf-8')) #對密碼加鹽 m.update(password.encode('utf-8')) print(m.hexdigest())
?
hmac模塊的加密方式,與hashlib差不多:
'''python 還有一個 hmac 模塊,它內部對我們創建 key 和 內容 進行進一步的處理然后再加密:''' import hmac h = hmac.new('天王蓋地虎'.encode('utf8')) #hmac必須要加鹽 h.update('hello'.encode('utf8')) print(h.hexdigest()) #1abaae8f65f68f2695a8545c5bc8e738#要想保證hmac最終結果一致,必須保證: #1:hmac.new括號內指定的初始key一樣 #2:無論update多少次,校驗的內容累加到一起是一樣的內容 # 下面單重方式得到的結果是一樣的 import hmac h1=hmac.new(b'tom') #初始值必須保證一致,最終得到的結果就會不一樣 h1.update(b'hello') h1.update(b'world') print(h1.hexdigest())h2=hmac.new(b'tom') #初始值必須保證一致,最終得到的結果就會不一樣 h2.update(b'helloworld') print(h2.hexdigest())h3=hmac.new(b'tomhelloworld') #初始值不一樣,所以與上面兩種的結果不一樣 print(h3.hexdigest())
結果如下:
0426ccec3b134e8c18fdcefee841ef25
0426ccec3b134e8c18fdcefee841ef25
ff1214d895bbaf5f1847db4ebae8212e
?
破解用戶的密碼:
# 重點 '''模擬撞庫破解密碼''' import hashlib passwds=[ #可以通過random實現對passwds中的內容'alex3714','alex1313','alex94139413','alex123456','123456alex','a123lex',]def make_passwd_dic(passwds): #通過明文密碼列表,造出與之對應的hash值得字典dic={}for passwd in passwds:m=hashlib.md5() #使用md5算法,造了一個工廠m.update(passwd.encode('utf-8')) #給工廠運送原材料(即我們要加密的內容)dic[passwd]=m.hexdigest() #產出hash值(即最終的產品),將其加入到我們事先造好的空字典中,字典形式:{密碼:hash值}return dicdef break_code(cryptograph,passwd_dic): #判斷攔截的hash值是否與字典中事先造好的hash值相等,相等則說明成功進行破解for k,v in passwd_dic.items():if v == cryptograph:print('密碼是===>\033[46m%s\033[0m' %k)cryptograph='aee949757a2e698417463d47acac93df' #我們攔截拿到的密碼,經過加密的hash值 break_code(cryptograph,make_passwd_dic(passwds)) #將要破解的密碼hash值,和事先造好的hash的字典當做函數的實參傳給對應的形參
?