由於在之後的演算法中會用到HMAC-SHA256函式,這裡先簡單對其進行一個介紹。
一、HMAC演算法
- 什麼是HMAC演算法?
HMAC是金鑰相關的雜湊運算訊息認證碼(Hash-based Message Authentication Code)的縮寫,由H.Krawezyk,M.Bellare,R.Canetti於1996年提出的一種基於Hash函式和金鑰進行訊息認證的方法,並於1997年作為RFC2104被公佈,並在IPSec和其他網路協議(如SSL)中得以廣泛應用,現在已經成為事實上的Internet安全標準。它可以與任何迭代雜湊函式捆綁使用。[3]
簡單地說就是:HMAC是一種使用單向雜湊函式來構造訊息認證碼的演算法。
HMAC演算法利用雜湊運算,以一個金鑰和一個訊息為輸入,生成一個訊息摘要作為輸出。其安全性是建立在Hash加密演算法基礎上的。它要求通訊雙方共享金鑰、約定演算法、對報文進行Hash運算,形成固定長度的認證碼。通訊雙方通過認證碼的校驗來確定報文的合法性。HMAC演算法可以用來作加密、數字簽名、報文驗證等[2]。HMAC使用的Hahs函式並不僅限於一種,任何高強度的單向雜湊函式都可以被用於HMAC,如果將來設計出的新的單向雜湊函式,也同樣可以使用。使用SHA-1、SHA-224、SHA-256、SHA-384、SHA-512所構造的HMAC,分別稱為HMAC-SHA1、HMAC-SHA-224、HMAC-SHA-256、HMAC-SHA-384、HMAC-SHA-512[1]。其中HMAC-SHA256就是接下來要重點介紹的。
定義1 HMAC演算法
HMAC演算法的數學公式為:
HMAC ( k , m ) = H ( k’ ⊕ opad , H ( k’ ⊕ ipad, m ) )
其中:
H 為密碼Hash函式(如MD5或SHA-2),能夠對明文進行分組迴圈壓縮;
k 為金鑰(secret key);
m 為要認證的訊息;
k’ 是從原始金鑰 k 匯出的另一個金鑰(如果 k 短於雜湊函式的輸入塊大小,則向右填充零;如果比該塊大小更長,則對 k 進行雜湊)
ipad 內部填充(0x5C5C5C…5C5C,一段十六進位制常量);
opad 外部填充(0x363636…3636,一段十六進位制常量)。
1.1 HMAC的計算步驟
HMAC計算步驟如下圖所示:
① 金鑰處理
如果金鑰比單向雜湊函式分組長度要短,就需要在末尾填充0,直到其長度達到單向雜湊函式的分組長度為止。
如果金鑰比分組長度要長,則要用單向雜湊函式求出金鑰的雜湊值,然後將這個雜湊值用作HMAC的金鑰。
② 處理後的金鑰與ipad進行XOR
將處理後的金鑰與被稱為ipad的位元序列進行XOR運算。ipad是將00110110這一位元序列不斷迴圈反覆直到達到分組長度所形成的位元序列,其中ipad的i是inner的意思。
XOR運算所得到的值,是一個和單向雜湊函式的分組長度相同,且和金鑰相關的位元序列。這裡將這個位元序列稱為ipadkey。
③ 與訊息組合
隨後,將ipadkey與訊息組合,也就是將和金鑰相關的位元序列(ipadkey)附加在訊息的開頭。
④ 計算雜湊值
將步驟③的結果作為單向雜湊函式的輸入,並計算出雜湊值。
⑤ 處理後的金鑰與opad進行XOR
將填充後的金鑰與被稱為opad的位元序列進行XOR運算,opad是將01011100這一位元序列不斷迴圈反覆直到達到分組長度所形成的位元序列,其中opad的o是outer的意思。
XOR運算所得到的結果也是一個和單向雜湊函式的分組長度相同,且和金鑰相關的位元序列。這裡將這個位元序列稱為opadkey。
⑥ 與雜湊值組合
將步驟④的結果拼在opadkey的後面。
⑦ 計算雜湊值
將步驟⑥的結果輸入單向雜湊函式,並計算出雜湊值,這個雜湊值就是最終的MAC值。
通過上述流程可以看出,最後得到的MAC值,一定是一個和輸入的訊息以及金鑰都相關的長度固定的位元序列。
二、SHA-256演算法
- 什麼是SHA-256演算法?
雜湊函式它被認為是一種單向函式——根據函式輸出的結果,極難回推輸入的資料。雜湊函式把訊息資料打亂混合,壓縮成雜湊值(摘要),使得資料量變小。
SHA-256由美國國家安全域性研發,是SHA-2下細分出的一種演算法,屬於SHA演算法之一,是SHA-1的後繼者。SHA-256(Secure Hash Algorithm 256,安全雜湊演算法256)是雜湊函式(或雜湊函式)的一種,對於任意長度的訊息,SHA256都會產生一個256-bit(32-byte陣列)的雜湊值,稱作訊息摘要。。摘要通常用一個長度為64位的十六進位制字串來表示。當接收到訊息的時候,這個訊息摘要可以用來驗證資料是否發生改變,即驗證其完整性。[2]
2.1 SHA-256的演算法描述
首先進行資訊預處理,如下圖所示,將原始訊息分成若干個512-bit大小的訊息塊。最後一個訊息塊需要進行資訊補全,並附上原訊息的長度資訊。訊息被分成n塊後,需要進行n次迭代,最後一次的結果就是最終的雜湊值,即256bit的數字摘要。
SHA256演算法的最小運算單元為“字”(word, 32-bit)。下圖的256-bit的中間狀態Hi被描述為8個字。512-bit的訊息塊Mi將由16個字擴充套件為64個字,並與Hi混合,壓縮成新的雜湊值Hi+1。第i塊資料經Map函式對映的結果,將作為第i+1塊的輸入,即Map(H_(i-1))=H_i。H0是預設好的hash初值(自然數中前8個質數的平方根的小數部分,取前32-bit),依次對資料進行Hash對映,得到的最後一個狀態Hn便是最終的數字摘要。
而其中最關鍵的操作為對映函式Map,其內部相當於是一個迴圈加密的過程,不斷將原始資訊進行打亂。
2.2 SHA-256的演算法步驟
下面兩個表列出了SHA256雜湊函式中涉及到的所有邏輯運算,運算均是按位進行的。
設原始訊息為M,原始訊息長度LM,訊息塊Mi,雜湊初值H0,SHA-256常量K[0]~K[63](自然數中前64個質數的立方根的小數部分,取前32-bit)。則SHA-256演算法的加密步驟具體如下:
① 訊息(M)預處理
在訊息末尾進行新增一位“1”和t位“0”,使得:
(L_M+t+1) mod 512=448,0≤t<512
將LM表示為64位大端儲存格式,並新增到M末尾,組成新的訊息M^’;
② 分解
將M^'按照每塊512-bit大小分解為Mi;
③ 擴充Mi到64字:W[0]~W[63]
將Mi分解為16個32-bit的大端儲存的字(word),存為W[0], …, W[15],其餘字由以下公式得到:
W_t=σ_1 (W_(t-2))+W_(t-7)+σ_0 (W_(t-15))+W_(t-16)
④ 迭代
進行64次加密迴圈即可完成一次迭代。加密過程如圖4所示:ABCDEFGH這8個字最開始分別是8個雜湊初值,之後按照圖示規則進行更新;深藍色方塊是事先定義好的非線性邏輯函式;紅色方塊代表加法(若結果大於232,則進行一次mod 232運算);Kt為SHA-256常量,Wt為本區塊產生第t個word,0≤t<64;最後一次迴圈所產生的八段字串合起來即是此區塊對應到的雜湊字串;
⑤ 若原訊息包含數個區塊,則最後還要將這些區塊產生的雜湊字串加入迭代才能產生最後的雜湊字串。
三、HMAC-SHA256演算法
3.1 HMAC-SHA256的演算法描述
HMAC-SHA256演算法,即使用SHA-256生成雜湊值的HMAC演算法。依據HMAC演算法和SHA-256演算法內容,可知HMAC-SHA256演算法的明文分組長度B為512-bit,可通過任意長度金鑰K(最小推薦長度為256-bit,一般應大於B),得出長度為256-bit雜湊值(摘要)。定義為:
〖HMAC〗_SHA256 (k,m)= SHA256(k’⊕opad∥SHA256(k’⊕ipad∥m))
其中:
SHA256 為SHA-256加密演算法,其輸出雜湊值長度256-bit;
|| 拼接操作,將兩個字串拼接在一起;
B Hash函式明文分組長度,SHA-256演算法中為512-bit;
k 為金鑰(secret key);
m 為要認證的訊息;
k’ 是從原始金鑰 k 匯出的另一個金鑰(若 k 短於B,則向右填充零,直到與B相同;若k長於B,則對 k 進行一次SHA256雜湊計算)
ipad 內部填充(0x5C5C5C…5C5C,512-bit常量);
opad 外部填充(0x363636…3636,512-bit常量)。
3.2 HMAC-SHA256的演算法步驟
HMAC-SHA256計算步驟如下圖所示:
① 金鑰處理
如果金鑰比SHA-256分組長度(512-bit)要短,就需要在末尾填充0,直到其長度達到單向雜湊函式的分組長度為止。
如果金鑰比SHA-256分組長度(512-bit)要長,則要用SHA-256演算法求出金鑰的雜湊值,然後將這個雜湊值用作HMAC的金鑰。
② 處理後的金鑰與ipad進行XOR
將處理後的金鑰與被稱為ipad的位元序列進行XOR運算。ipad是將00110110這一位元序列不斷迴圈反覆直到達到SHA-256分組長度(512-bit)所形成的位元序列,其中ipad的i是inner的意思。
XOR運算所得到的值,是一個和SHA-256分組長度(512-bit)相同,且和金鑰相關的位元序列。這裡將這個位元序列稱為ipadkey。
③ 與訊息組合
隨後,將ipadkey與訊息組合,也就是將和金鑰相關的位元序列(ipadkey)附加在訊息的開頭。
④ 計算雜湊值
將步驟③的結果作為SHA-256函式的輸入,並計算出雜湊值。
⑤ 處理後的金鑰與opad進行XOR
將填充後的金鑰與被稱為opad的位元序列進行XOR運算,opad是將01011100這一位元序列不斷迴圈反覆直到達到SHA-256分組長度(512-bit)所形成的位元序列,其中opad的o是outer的意思。
XOR運算所得到的結果也是一個和SHA-256分組長度(512-bit)相同,且和金鑰相關的位元序列。這裡將這個位元序列稱為opadkey。
⑥ 與雜湊值組合
將步驟④的結果拼在opadkey的後面。
⑦ 計算雜湊值
將步驟⑥的結果輸入SHA-256函式,並計算出雜湊值,這個雜湊值就是最終的摘要內容。
通過上述流程可以看出,最後得到的摘要內容,一定是一個和輸入的訊息以及金鑰都相關的長度固定的位元序列。
參考:
[2] 從零入門HMAC-SHA256
[3] HMAC百度百科