1、HMAC 概念
HMAC(Hash-based Message Authentication Code)基於 hash 的消息驗證碼,是 安全通信中必要的組成部件。
主要是 防止消息被篡改,和對稱加密一起保護數據通信的 完整性。
參考HMAC實現規范,基於的 Hash 算法可以是 md5,sha1,sha-2(sha256,sha385,sha512)等;
在不考慮 hash算法具體實現的情況下,其實現原理圖如下:
1)密鑰填充:
如果密鑰比Hash函數的分組長度(block_size)要長,則要用Hash函數求出密鑰的散列值,然后將這個散列值用作HMAC的密鑰。
如果密鑰比分組長度要短,就在末尾填充0,直到其長度達到單向散列函數的分組長度為止。
注:散列值長度digest_size 一般都會短於 分組長度block_size,因此,實際上 長於分組長度計算散列值之后,仍然需要在尾部填0。
2)填充后的密鑰與ipad的XOR 將填充后的密鑰,與被稱為ipad的比特序列進行XOR運算。
ipad是將00110110這一比特序列(即16進制的36) 不斷循環反復直到達到分組長度所形成的比特序列。其中:ipad的i 是inner的意思。
XOR運算所得到的值,就是一個和單向散列函數的分組長度相同,且和密鑰相關的比特序列。這里我們將這個比特序列成為ipadkey。
3)與消息結合 將ipadkey與消息進行組合,也就是將和密鑰相關的比特序列(ipadkey)附加在消息的開頭。
4)計算散列值 將步驟3的結果輸入單向散列函數,並計算出散列值。
5)填充后的密鑰與opad的XOR 將填充后的密鑰與被稱為opad的比特序列進行XOR運算。
opad是將01011100這一比特序列(即十六進制5C)不斷循環反復直到達到分組長度所形成的比特序列,其中opad的o是outer的意思。
XOR運算所得到的結果也是一個和單向散列函數的分組長度相同,且和密鑰相關的比特序列。這里我們將這個比特序列稱為opadkey。
6)與散列值組合 opadkey附加在步驟4的散列值前面。
7)計算散列值 將步驟6的結果輸入單向散列函數,並計算出散列值。這個值就是最終的MAC值。
2、HMAC Python hmac庫實現
在 Python 中, 直接提供了 hmac 庫實現相關操作。
如下所示,是yvivid基於 hmac庫的一個實現。
更多hmac庫的使用,請參考 python doc。
3、HMAC 的 笨辦法( 僅利用Python hashlib庫實現)
基於HMAC的原理,是否可以在已有 hash算法上,自己實現 HMAC算法。
下面是 yvivid 在 Python上,基於 hashlib庫(hash算法)的基礎上,HMAC自行編碼的一個實現的。
1)由於 需要 XOR是實現,因此 使用了 int 和 bytes的轉換,寫的不是很簡潔(邏輯電路的思維)。
2) i_key_pad 和 o_key_pad 實際上展開到 block_size長度了。
注:其實 在自己實現時,還沒注意到 python的 hmac 庫,結果是自己摸索 和 openssl輸出進行對比分析的。
大家可自己分析 Python36\Lib\hmac.py 的代碼。部分處理比我寫的簡潔,使用了 bytes的 ljust,translate特性。
但只有自己實現 才能感覺到其真實的原理。
4、易混淆的概念
1)填充階段,尤其是 分組長度block_size 和 摘要(散列值)長度digest_size,
描述的概念比較混淆,導致編寫代碼過程走了彎路。
分組長度block_size 是 Hash 處理輸入數據時,是按照 block_size大小來分塊(block)處理的。
摘要(散列值)長度digest_size 是 Hash完成后,輸出的 摘要(散列值)字節長度。
2)XOR 階段,yvivid的實現采用了並行的思路,基於整數 的異或操作(python語法的 ^)。
3)Python 語法方面,對於 bytes 還是不熟悉,需要進一步學習。
附錄:常用散列算法的分組長度和摘要長度。
單向散列函數 | 分組長度 block_size | 摘要長度digest_size |
MD5 | 64 Bytes (512bit) | 16 Bytes (128bit) |
SHA1 | 64 Bytes (512bit) | 20 Bytes (160bit) |
SHA256 | 64 Bytes (512bit) | 32 Bytes (256bit) |
SHA512 | 128 Bytes (1024bit) | 64 Bytes (512bit) |
原創聲明:
HMAC原理是公共的,但 python代碼實現(尤其是 基於hashlib下 自己的編寫),是基於本人在 python 實現,轉載請聲明出處。
https://www.cnblogs.com/yvivid/p/hmac_basic.html
參考文獻:
1) 圖解密碼技術(第3版) ,[日]結城浩;
學習筆記:http://flamepeak.com/2016/11/23/tu-jie-mi-ma-ji-shu-authentication20161123/
2) Python 3.6.8 documentation / Library Reference
hashlib — Secure hashes and message digests
hmac — Keyed-Hashing for Message Authentication
3)擴展閱讀(文章寫完后發現的):
HMAC算法原理:https://www.cnblogs.com/shoshana-kong/p/11497676.html