程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> 關於VC++ >> 基於SHA-256的HMAC文件校驗器

基於SHA-256的HMAC文件校驗器

編輯:關於VC++

HMAC即帶密鑰的HASH函數,用它產生的報文鑒別碼(MAC)可以實現報文鑒別 。這裡我將其做成一個軟件,用於對文件的合法性進行校驗。以下我先簡單介紹 軟件相關背景知識再介紹其代碼實現。

一、背景知識簡介

有時候 進行通信的雙方基於安全的考慮需要對對方發過來的消息進行校驗,以確定消息 是未經第三方修改過的。這種校驗可以這樣進行:

雙方共同約定一個密鑰( 即一個密碼),這個密鑰是對第三方保密的;

消息的發方使用該密鑰對將發 送的消息產生一個校驗碼,並把該校驗碼附在消息後一起發出;

消息的接收 方在接收到附有校驗碼的消息後,將消息和校驗碼分開,用密鑰對該消息生成一 個校驗碼;

然後將兩個校驗碼相比較,如果相同的話則說明消息是未經第三 方修改的,如果不同的話說明消息很可能被非法修改過(當然也有可能是別的原 因使消息改變了)則該消息不可信,需要對方重發 ;

*其中,生成校驗碼的 算法一般采用HMAC,它保證了第三方在不知密鑰的情況下,不可能在修改消息後 可以同時修改校驗碼使之與修改後的消息匹配。

*在整個過程中消息是公 開的(未經加密的),算法只提供消息的完整性校驗而不提供保密性,保密性可 由公鑰加密算法現實,這裡不作討論。

二、軟件的實現

我做的該 軟件是可以對電腦磁盤上的任意一文件生成一校驗文件.vri(密鑰由用戶自己輸 入),根據該校驗文件可以在需要之時對相應的文件進行校驗。具體做法將在後 面的例子中給出。

程序中的HMAC算法的HASH函數我采用的是SHA-256算法 ,它比起MD5和SHA-1來要安全。(其實因為不是正式的安全產品,所以在本程序 中采用MD5或SHA-1也未嘗不可)。

*HMAC的結構如下圖所示:

圖一 HMAC的結構

圖中各符號定義如下:

IV =作為HASH函數輸入的 初始值
M =HMAC的消息輸入
Yi =M的第i個分組,0<=i<=(L- 1)
b =每一分組所含的位數
n =嵌入的HASH函數所產生的HASH碼長
K =密鑰
K+ =為使K為b位長而在K左邊填充0後所得的結果
ipad =0x36重復b/8次的結果
opad =0x5c重復b/8次的結果

對 於特定的HASH函數,b、n都是固定的,所以在程序的HMAC類中,n被定義為宏Mn ,b被定義為Mb,值分別為32和64。由於該結構的效率較低,不利於實用化。於 是有人提出了一個HMAC的高效實現方案。

*HMAC的有效實現方案如下:

圖二 HMAC的有效實現方案

其中的HASH即為SHA-256。

圖中左邊所示為 預計算,右邊為對每條消息的計算。在密鑰不變的情況下只需進行一次預計算, 以後在產生校驗碼時就只用到右邊的計算了。這樣就可以提高效率。

需 要說明的是,大家在閱讀我寫的HMAC的類可能會發現,在每次計算時都進行了左 右兩邊的計算(不論密鑰怎樣)。這是因為我考慮到個人用戶可能會不時地對密 鑰進行更換,並且應用場合也不對效率有特別的要求。當然這樣做並沒有體現出 HMAC有效實現方案的優點。

另外還有一點就是我對密鑰的填充是填充的 低位,即密鑰右邊,這和上述方案有不同(方案上說是要填充在高位,即左邊) ,在此說明,以使大家在看源代碼的時候不至於疑惑。

以上有效實現方 案在HMac類中現實,HASH函數sha-256在Sha256類中實現。由於這裡主要說的是 HMAC,sha-256只是作為一個黑盒子,所以不多解釋。

程序中的Mac類與 HAMC和HASH函數都無關,只是一個存放結果的介質,它甚至都沒有成員函數,我 也在考慮是不是可以不把它做成一個類。

為了便於讀者閱讀HMac類中的 各變量基本上采用圖二中的各標識符標識。

對於下面一段代碼讀者可能 會有疑惑,明明是該得到第一個預計算的結果,m_dwA1—m_dwH1是什麼呢 ?

for(i=0;i<Mb;i++)
  S[i]=sKeyplus[i]^ipad[i];
m_sha256.Init(Mb);
m_sha256.GenW(S,Mb);
m_sha256.Steps ();
m_dwA1=m_sha256.OA;
m_dwB1=m_sha256.OB;
m_dwC1=m_sha256.OC;
m_dwD1=m_sha256.OD;
m_dwE1=m_sha256.OE;
m_dwF1=m_sha256.OF;
m_dwG1=m_sha256.OG;
m_dwH1=m_sha256.OH;

其實 m_dwA1—m_dwH1就是第一個預計算的輸出。這裡因為這個輸出有256位,於 是我把它拆成了8個32位。同理,第二個預計算的輸出為m_dwA2—m_dwH2。

此外,程序中關於文件拖放和文件保存打開的部分(包括串行化等)對 於初學者來說都是一個不錯的借鑒,當然高手就不需在意了。下面將給出一個例 子使讀者的認識感性化一點。

三、例子

我有一張非常重要的圖片 傳給你,如下:

圖三 例圖 VeriFileimg3

在傳這張圖的同時附上它的校驗文件 “important.vri”。(該校驗文件在源代碼壓縮包)

而你收 到的圖片如下:(它在傳送中在8,46處被非法的第三方修改了一個象素)

圖四 例圖VeriFileimg4

你用該軟件對其進行校驗可以如下操作:

運行該軟 件,打開important.vri(打開方式有兩種,你可以從菜單‘文件-打開 ’中打開,也可以直接把文件拖進程序窗口中。)

(第一次運行該 軟件後,程序會創建一個對vri文件的關聯,以後打開vri文件就能以雙擊vri文 件打開了。);

將要校驗的文件拖入程序窗口中,在彈出的對話框中選否; 或者是從菜單‘校驗文件-驗證源文件’中打開;

然後程序要求輸 入校驗密鑰,這裡你和我約定的密鑰為gamsn,也就是輸入gamsn;

程序會計算源文件的校驗碼值,並告訴你結果;

由源文件生成校驗文件的操作也很簡 單,從菜單‘校驗文件-生成校驗文件’中選中你的源文件,然後在 彈出的對話框中輸入密鑰就可以了。提醒一下,密鑰最大有效長度為16字節,中 英文不限。生成的校驗文件都自動以vri為後綴名。

四、結束語

大概情況就是如此,大家有什麼問題或指正可以與我聯系,謝謝!

另外 如果諸君對HASH函數感興趣的話可以參考 William Stallings 的 Cryptography and Network Security Principles and Practices 一書第三版。該書不是編程方面的指南,而是密碼與網安方面的專業教材。它的中文版也譯得不錯,是一本 好書。

本文配套源碼

  1. 上一頁:
  2. 下一頁:
欄目導航
Copyright © 程式師世界 All Rights Reserved