1. 程式人生 > >信息摘要算法之五:HMAC算法分析與實現

信息摘要算法之五:HMAC算法分析與實現

UC str 就是 n) auth 如果 輸出 返回 digest

MAC(Message Authentication Code,消息認證碼算法)是含有密鑰散列函數算法,兼容了MD和SHA算法的特性,並在此基礎上加上了密鑰。因此MAC算法也經常被稱作HMAC算法。

1HMAC概述

HMAC算法首先它是基於信息摘要算法的。目前主要集合了MD和SHA兩大系列消息摘要算法。其中MD系列的算法有HmacMD2、HmacMD4、HmacMD5三種算法;SHA系列的算法有HmacSHA1、HmacSHA224、HmacSHA256、HmacSHA384、HmacSHA512五種算法。

HMAC算法除了需要信息摘要算法外,還需要一個密鑰。HMAC的密鑰可以是任何長度,如果密鑰的長度超過了摘要算法信息分組的長度,則首先使用摘要算法計算密鑰的摘要作為新的密鑰。一般不建議使用太短的密鑰,因為密鑰的長度與安全強度是相關的。通常選取密鑰長度不小於所選用摘要算法輸出的信息摘要的長度。

2HMAC算法分析

HMAC算法本身並不復雜,起需要有一個哈希函數,我們記為H。同時還需要有一個密鑰,我們記為K。每種信息摘要函數都對信息進行分組,每個信息塊的長度是固定的,我們記為B(如:SHA1為512位,即64字節)。每種信息摘要算法都會輸出一個固定長度的信息摘要,我們將信息摘要的長度記為L(如MD5為16字節,SHA-1為20個字節)。正如前面所述,K的長度理論上是任意的,一般為了安全強度考慮,選取不小於L的長度。

HMAC算法其實就是利用密鑰和明文進行兩輪哈希運算,以公式可以表示如下:

HMAC(K,M)=H(K⊕opad∣H(K⊕ipad∣M)),其中:

Ipad為0x36重復B次

Opad為0x5c重復B次

M 代表一個消息輸入

根據上面的算法表示公式,我們可以描述HMAC算法的運算步驟:

(1)、檢查密鑰K的長度。如果K的長度大於B則先使用摘要算法計算出一個長度為L的新密鑰。如果後K的長度小於B,則在其後面追加0來使其長度達到B。

(2)、將上一步生成的B字長的密鑰字符串與ipad做異或運算。

(3)、將需要處理的數據流text填充至第二步的結果字符串中。

(4)、使用哈希函數H計算上一步中生成的數據流的信息摘要值。

(5)、將第一步生成的B字長密鑰字符串與opad做異或運算。

(6)、再將第四步得到的結果填充到第五步的結果之後。

(7)、使用哈希函數H計算上一步中生成的數據流的信息摘要值,輸出結果就是最終的HMAC值。

由上述描述過程,我們知道HMAC算法的計算過程實際是對原文做了兩次類似於加鹽處理的哈希過程。

3、代碼實現

前面我們描述了HMAC算法及其實現過程,接下來我們則將其實現。首先我們定義一個用於保存計算過程上下文的結構:

/** 該結構將為HMAC密鑰哈希操作保存上下文信息*/

typedef struct HMACContext {

int whichSha; /* 所用的SHA算法 */

int hashSize; /* 所用SHA的哈希值大小 */

int blockSize; /* 所用SHA塊的大小 */

SHAContext shaContext; /* SHA上下文 */

unsigned char k_opad[SHA_Max_Message_Block_Size];/* outer padding - key XORd with opad */

int Computed; /* Is the MAC computed? */

int Corrupted; /* Cumulative corruption code */

} HMACContext;

接下來實現HMAC初始化函數。這個函數將初始化hmacContext以準備計算一個新的HMAC消息摘要。

int hmacReset(HMACContext *context, enum SHAversion whichSha,const unsigned char *key, int key_len)

{

int i, blocksize, hashsize, ret;

unsigned char k_ipad[SHA_Max_Message_Block_Size];/* inner padding - key XORd with ipad */

unsigned char tempkey[SHAMaxHashSize];/* temporary buffer when keylen > blocksize */

if (!context) return shaNull;

context->Computed = 0;

context->Corrupted = shaSuccess;

blocksize = context->blockSize = SHABlockSize(whichSha);

hashsize = context->hashSize = SHAHashSize(whichSha);

context->whichSha = whichSha;

/*如果鍵長於哈希塊大小,將其重置為key = hash (key)。 */

if (key_len > blocksize) {

SHAContext tcontext;

int err = SHAReset(&tcontext, whichSha) ||

SHAInput(&tcontext, key, key_len) ||

SHAResult(&tcontext, tempkey);

if (err != shaSuccess) return err;

key = tempkey;

key_len = hashsize;

}

/*將key與ipad和opad按位異或*/

for (i = 0; i < key_len; i++) {

k_ipad[i] = key[i] ^ 0x36;

context->k_opad[i] = key[i] ^ 0x5c;

}

/*將key填充0直到blocksize並與ipad和opad按位異或 */

for ( ; i < blocksize; i++) {

k_ipad[i] = 0x36;

context->k_opad[i] = 0x5c;

}

/* 開始內層哈希運算 */

ret = SHAReset(&context->shaContext, whichSha) ||

SHAInput(&context->shaContext, k_ipad, blocksize);

return context->Corrupted = ret;

}

接下來輸入將要處理的信息,這個函數接受一個字節數組作為消息的下一處理部分。

int hmacInput(HMACContext *context, const unsigned char *text,int text_len)

{

if (!context) return shaNull;

if (context->Corrupted) return context->Corrupted;

if (context->Computed) return context->Corrupted = shaStateError;

/* 報文內容 */

return context->Corrupted =SHAInput(&context->shaContext, text, text_len);

}

最後處理完成全部過程,返回信息摘要。此函數將返回相應大小的消息摘要,具體是多長的信息摘要由具體的SHA算法決定。

int hmacResult(HMACContext *context, uint8_t *digest)

{

int ret;

if (!context) return shaNull;

if (context->Corrupted) return context->Corrupted;

if (context->Computed) return context->Corrupted = shaStateError;

/* 完成內層哈希運算 */

ret =SHAResult(&context->shaContext, digest) ||

/* 執行外層哈希運算 */

SHAReset(&context->shaContext, context->whichSha) ||

SHAInput(&context->shaContext, context->k_opad,context->blockSize) ||

SHAInput(&context->shaContext, digest, context->hashSize) ||

SHAResult(&context->shaContext, digest);

context->Computed = 1;

return context->Corrupted = ret;

}

4、結果

我們已經實現了HMAC算法,接下來我們對其進行驗證。我們采用簡單的測試,取加密文本為text =“abcd”,設密鑰為key=“123456”,基於SHA-1的HMAC運算結果如下:

技術分享圖片

基於SHA-256的HMAC運算結果如下:

技術分享圖片

基於SHA-512的運算結果如下:

技術分享圖片

我們測試了HMAC-SHA1、HMAC-SHA256、HMAC-512三種情況,與在線HMAC加密算法進行對比計算,記過完全一致。

歡迎關註:

技術分享圖片

信息摘要算法之五:HMAC算法分析與實現