Python中HMAC加密算法的應(yīng)用
HMAC 算法可用于驗(yàn)證在應(yīng)用程序之間傳遞或存儲在潛在易受攻擊位置的信息的完整性。基本思想是生成與共享密鑰組合的實(shí)際數(shù)據(jù)的加密散列。然后,可以使用所得到的散列來檢查所發(fā)送或存儲的消息以確定信任級別,而不發(fā)送秘密密鑰。
簽名消息
new() 函數(shù)創(chuàng)建一個用于計算消息簽名的新對象。此示例使用默認(rèn)的 MD5 散列算法。
```python hmac_simple.py import hmac digest_maker = hmac.new(b'secret-shared-key-goes-here')with open('lorem.txt', 'rb') as f: while True: block = f.read(1024) if not block: break digest_maker.update(block)digest = digest_maker.hexdigest()print(digest)
運(yùn)行時,代碼讀取數(shù)據(jù)文件并為其計算 HMAC 簽名。
$ python3 hmac_simple.py
4bcb287e284f8c21e87e14ba2dc40b16
可選的摘要類型
盡管默認(rèn)的 hmac 算法是 MD5,但那不是最安全的方法。MD5 摘要算法有一些缺點(diǎn),例如碰撞?(兩個不同的消息產(chǎn)生了不同的哈希值)。SHA-1 被公認(rèn)為是比較健壯的,應(yīng)該使用它。
hmac_sha.py import hmac import hashlib digest_maker = hmac.new( b'secret-shared-key-goes-here', b'', hashlib.sha1,)with open('hmac_sha.py', 'rb') as f: while True: block = f.read(1024) if not block: break
digest_maker.update(block)digest = digest_maker.hexdigest()print(digest)
new() 函數(shù)接受三個參數(shù)值,第一個是密鑰,共享于兩個通信的端點(diǎn)之間,所以兩個端點(diǎn)都使用相同的值。第二個參數(shù)是初始化消息值。如果需要認(rèn)證的消息內(nèi)容非常小,例如時間戳或者 HTTP POST,那么整個消息體可以傳入 new() 而不用 update() 方法。最后一個參數(shù)是要使用的摘要算法。默認(rèn)的是 hashlib.md5,例子中使用的是 hashlib.sha1。
$ python3 hmac_sha.py
dcee20eeee9ef8a453453f510d9b6765921cf099
二進(jìn)制摘要
前一個例子使用了 hexdigest() 方法生成可打印的摘要字符串。這個摘要字符串是由 digest() 方法生成的值的不同表現(xiàn)形式而已,這
hmac_base64.py import base64 import hmac import hashlib with open('lorem.txt', 'rb') as f: body = f.read()hash = hmac.new( b'secret-shared-key-goes-here', body, hashlib.sha1,)digest = hash.digest()print(base64.encodestring(digest))
base64 編碼的字符串以換行符結(jié)尾,當(dāng)將字符串嵌入到 HTTP 頭或者其他敏感的上下文中時,經(jīng)常需要將這個換行符刪除。
$ python3 hmac_base64.py
b'olW2DoXHGJEKGU0aE9fOwSVE/o4=\n'
消息簽名的應(yīng)用
HMAC 算法應(yīng)該用于任何公共網(wǎng)絡(luò)服務(wù),并且任何數(shù)據(jù)都應(yīng)該存儲在安全性很重要的地方。例如,當(dāng)數(shù)據(jù)被通過管道或者 socket 發(fā)送的時候,數(shù)據(jù)應(yīng)該被簽名,然后在使用之前驗(yàn)簽。此處給出的擴(kuò)展示例位于文件 hmac_pickle.py。
第一步是創(chuàng)建一個函數(shù)計算一個字符串的摘要,以及一個簡單的類,用于實(shí)例化并通過通信通道傳遞。
hmac_pickle.py import hashlib import hmac import io import pickle import pprint def make_digest(message): "Return a digest for the message." hash = hmac.new( b'secret-shared-key-goes-here', message, hashlib.sha1, ) return hash.hexdigest().encode('utf-8')class SimpleObject: """Demonstrate checking digests before unpickling. """ def __init__(self, name): self.name = name def __str__(self): return self.name
接下來,創(chuàng)建一個 BytesIO 緩沖池代表一個 socket 或者管道。例子中使用了一個原生的,但是很容易解析的,格式化的數(shù)據(jù)流。首先數(shù)據(jù)的摘要和長度被寫入,后面緊跟了一個換行符。對象的序列化形式由 pickle 生成。真實(shí)的系統(tǒng)可能不希望依賴于長度值,因?yàn)槿绻e誤,則長度也是錯誤的。某些不太可能出現(xiàn)在實(shí)際數(shù)據(jù)中的終結(jié)符序列可能更加合適。
然后示例程序中往數(shù)據(jù)流中寫入了兩個對象。第一個是使用正確的摘要值寫入的。
使用緩沖區(qū)模擬可寫套接字或者管道
out_s = io.BytesIO()
往流中寫入一個有效的對象
digest\nlength\npickle
o = SimpleObject('digest matches') pickled_data = pickle.dumps(o) digest = make_digest(pickled_data) header = b'%s %d\n' % (digest, len(pickled_data)) print('WRITING: {}'.format(header)) out_s.write(header) out_s.write(pickled_data)
第二個寫入流中的對象使用了一個無效的摘要值,摘要值是由其他一些數(shù)據(jù)生成的而不是序列化之后的值。
往流中寫入一個無效的對象
o = SimpleObject('digest does not match') pickled_data = pickle.dumps(o) digest = make_digest(b'not the pickled data at all') header = b'%s %d\n' % (digest, len(pickled_data)) print('\nWRITING: {}'.format(header)) out_s.write(header) out_s.write(pickled_data) out_s.flush()
記住數(shù)據(jù)是在 BytesIO 緩沖池中的,它可以再次被讀出。首先讀取帶有摘要和數(shù)據(jù)長度的行。然后使用長度值讀取剩下的數(shù)據(jù)。pickle.load() 可以直接從流中讀取數(shù)據(jù),但是它假設(shè)一個可信任的數(shù)據(jù)流,而且這個數(shù)據(jù)還不足夠可信能夠反序列化它。從流中讀取序列化值為字符串,而不實(shí)際反序列化更安全。
使用 BytesIO 模擬可讀的 socket 或者管道
in_s = io.BytesIO(out_s.getvalue())
讀取數(shù)據(jù)
while True: first_line = in_s.readline() if not first_line: break incoming_digest, incoming_length = first_line.split(b' ') incoming_length = int(incoming_length.decode('utf-8')) print('\nREAD:', incoming_digest, incoming_length)
一旦序列化數(shù)據(jù)被讀取到內(nèi)存,摘要值可以被重新計算,并且使用 compare_digest() 同傳遞過來的數(shù)據(jù)比較。如果摘要匹配,證明它是安全的去信任數(shù)據(jù)并且反序列化它。
incoming_pickled_data = in_s.read(incoming_length) actual_digest = make_digest(incoming_pickled_data) print('ACTUAL:', actual_digest) if hmac.compare_digest(actual_digest, incoming_digest): obj = pickle.loads(incoming_pickled_data) print('OK:', obj) else: print('WARNING: Data corruption')
輸出表示第一個對象被驗(yàn)證通過,第二個被視為「損壞」。
$ python3 hmac_pickle.py
WRITING: b'f49cd2bf7922911129e8df37f76f95485a0b52ca 69\n'
WRITING: b'b01b209e28d7e053408ebe23b90fe5c33bc6a0ec 76\n'
READ: b'f49cd2bf7922911129e8df37f76f95485a0b52ca' 69
ACTUAL: b'f49cd2bf7922911129e8df37f76f95485a0b52ca'
OK: digest matches
READ: b'b01b209e28d7e053408ebe23b90fe5c33bc6a0ec' 76
ACTUAL: b'2ab061f9a9f749b8dd6f175bf57292e02e95c119'
WARNING: Data corruption
可以在定時攻擊中使用簡單的字符串或字節(jié)比較來比較兩個摘要,以通過傳遞不同長度的摘要來暴露部分或全部秘密密鑰。compare_digest() 實(shí)現(xiàn)了一個快速但是常量時間的比較函數(shù)去防止定時攻擊。
到此這篇關(guān)于Python中HMAC加密算法的應(yīng)用的文章就介紹到這了,更多相關(guān)Python HMAC內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python?matplotlib繪圖時使用鼠標(biāo)滾輪放大/縮小圖像
Matplotlib是Python程序員可用的事實(shí)上的繪圖庫,雖然它比交互式繪圖庫在圖形上更簡單,但它仍然可以一個強(qiáng)大的工具,下面這篇文章主要給大家介紹了關(guān)于Python?matplotlib繪圖時使用鼠標(biāo)滾輪放大/縮小圖像的相關(guān)資料,需要的朋友可以參考下2022-05-05Python 正則表達(dá)式 re.match/re.search/re.sub的使用解析
今天小編就為大家分享一篇Python 正則表達(dá)式 re.match/re.search/re.sub的使用解析,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-07-07機(jī)器學(xué)習(xí)之?dāng)?shù)據(jù)清洗及六種缺值處理方式小結(jié)
本文主要介紹了機(jī)器學(xué)習(xí)之?dāng)?shù)據(jù)清洗及六種缺值處理方式小結(jié),包括刪除空行、填充平均值、中位數(shù)、眾數(shù)、線性插值和隨機(jī)森林填充,具有一定的參考價值,感興趣的可以了解一下2025-03-03python判斷、獲取一張圖片主色調(diào)的2個實(shí)例
一幅圖片,想通過程序判斷獲得其主要色調(diào),應(yīng)該怎么樣處理?本文通過python實(shí)現(xiàn)判斷、獲取一張圖片的主色調(diào)方法,需要的朋友可以參考下2014-04-04opencv-python+yolov3實(shí)現(xiàn)目標(biāo)檢測
因?yàn)樽罱娜蝿?wù)有用到目標(biāo)檢測,快速地了解了目標(biāo)檢測這一任務(wù),并且實(shí)現(xiàn)了使用opencv進(jìn)行目標(biāo)檢測。感興趣的可以了解一下2021-06-06Python線程創(chuàng)建和終止實(shí)例代碼
這篇文章主要介紹了Python線程創(chuàng)建和終止實(shí)例代碼,小編覺得還是挺不錯的,具有一定借鑒價值,需要的朋友可以參考下2018-01-01python?dowhy數(shù)據(jù)估計因果分析功能探索
這篇文章主要為大家介紹了python?dowhy數(shù)據(jù)估計因果分析功能實(shí)例探索,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-02-02分位數(shù)回歸模型quantile regeression應(yīng)用詳解及示例教程
這篇文章主要為大家介紹了介紹了分位數(shù)回歸quantile regeression的概念詳解及代碼示例教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助2021-11-11