2010-01-28 17 views
0

我需要實現MD5校驗和以驗證XML文件中的MD5校驗和,其中包含所有XML標記以及從客戶端接收到的XML標記。接收到的MD5校驗和的長度是32個字節的十六進制數字。C中針對XML文件的MD5實現

在校驗和計算之前,我們需要設置MD5校驗和字段在接收到的XML文件中爲0,我們必須獨立計算並驗證接收到的XML文件中的MD5校驗和值。

我們的應用程序在C中實現請幫助我如何實現這一點。

感謝

+3

谷歌「MD5 C」彈出一堆基於頭的實現。 –

+0

你的意思是你想把整個XML文件當作一個大的文本文件,對吧?或者你必須以某種方式查看XML內部? –

+0

是的,我想將整個XML文件視爲一個大文件。客戶端MD5校驗和也可在該XML文件中使用。我需要在計算之前將該MD5校驗和替換爲0。 – Thi

回答

4

這直接取決於用於XML解析的庫。然而,這很棘手,因爲除了僅從特定元素執行校驗和之外,不能將MD5嵌入到XML文件本身中,以便在嵌入校驗和之後。據我瞭解,您獨立收到MD5?它是從整個文件計算出來的,還是隻有標籤/內容?

精確解取決於所使用的代碼。

基於您的評論你需要做以下步驟:

  • 加載XML文件(甚至可能爲純文本)讀取MD5
  • 替代的MD5與零的文件,寫入文件下來(或更高內存)
  • 運行MD5的純文件數據,並與前
+0

是的我想將整個XML文件視爲一個大文件。客戶端MD5校驗和也可在該XML文件中使用。我需要在計算之前將該MD5校驗和替換爲0。 – Thi

+1

「然而這很棘手,因爲你不能將MD5嵌入XML文件本身。」聽起來好像要構建的過程是「將校驗和字段設置爲零的文檔; MD5sum它;用值替換0」。要驗證是「查找校驗和值並替換爲0; MD5sum它;比較結果與刪除的值」。 –

1

有MD5,你應該使用,而不是寫你自己的公共領域的實現。我聽說Colin Plumb的版本被廣泛使用。

0

這是相當討厭的。建議的方法似乎意味着您需要將XML文檔解析爲DOM樹,找到MD5校驗和並將其存儲以供將來參考。然後,在重新序列化文檔並計算它的MD5哈希值之前,您將用0替換校驗和。這一切聽起來可行但可能會很棘手。我看到的主要困難是您的文檔的新序列化可能與原始序列化不同,而與屬性值的單引號或雙引號的使用,添加的換行符或甚至不同的編碼等不相關(與XML)的差異將會不相同導致哈希差異。如果您沿着這條路線走下去,您需要確保您的應用程序和用於創建文檔的過程首先作出相同的選擇。對於這類問題,規範XML是標準解決方案(http://www.w3.org/TR/xml-c14n)。

但是,我會做一些不同的事情。運氣好的話,應該很容易編寫一個正則表達式來定位文件中的MD5哈希,並將其替換爲0.然後,您可以在重新計算哈希之前使用它來獲取哈希並將其替換爲XML文件中的0。這避免瞭解析,更改和重新序列化XML文檔的所有可能的問題。爲了說明我要去承擔哈希「33d4046bea07e89134aecfcaf7e73015的生活像這樣的XML文件中:

<docRoot xmlns='some-irrelevant-uri> 
    <myData>Blar blar</myData> 
    <myExtraData number='1'/> 
    <docHash MD5='33d4046bea07e89134aecfcaf7e73015' /> 
    <evenMoreOfMyData number='34'/> 
</docRoot> 

(我已經叫hash.xml),該MD5應該由32個零來代替(這樣散列是正確的),並說明使用perl,md5和bash的shell命令行上的過程。 (希望將其轉換爲C不會太難,因爲存在正則表達式和哈希庫。)

打破該問題,首先需要能夠找到文件中的哈希:

perl -p -e'if (m#<docHash.+MD5="([a-fA-F0-9]{32})#) {$_ = "$1\n"} else {$_ = ""}' hash.xml 

(這個工作是通過尋找docHash元素的MD5屬性的開始,允許可能的其他屬性,然後抓住接下來的32個十六進制字符,如果它發現它們將它們灌入魔法$ _變量如果不是,則設置$ _爲空,那麼$ _的值將被打印爲每行,這導致打印字符串「33d4046bea07e89134aecfcaf7e73015」。)

然後,你需要計算該文件的哈希值與已用零代替:

perl -p -e's#(<docHash.+MD5=)"([a-fA-F0-9]{32})#$1"000000000000000000000000000000#' hash.xml | md5 

(其中正則表達式幾乎是相同的,但這次的十六進制字符由零和整體更換文件被打印。然後通過md5哈希程序對結果進行管道計算來計算MD5。與位的bash放在一起這給出:

if [ `perl -p -e'if (m#<docHash.+MD5="([a-fA-F0-9]{32})#) {$_ = "$1\n"} else {$_ = ""}' hash.xml` = `perl -p -e's#(<docHash.+MD5=)"([a-fA-F0-9]{32})#$1"000000000000000000000000000000#' hash.xml | md5` ] ; then echo OK; else echo ERROR; fi 

其執行這兩個小命令,輸出並輸出「OK」,如果輸出匹配或「ERROR」,如果他們不相比較。顯然,這只是一個簡單的原型,而且語言錯了,我認爲它說明了最直接的解決方案。

順便說一句,爲什麼你把哈希裏面的XML文件?據我所知,與在旁道上傳遞散列相比,它沒有任何優勢(甚至像第二個名爲documentname.md5的文件那樣簡單),並且使得散列驗證更加困難。