HMAC(Hash-based Message Authentication Code)實現原理


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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM