MD5的Java Bean實現

來源:互聯網
上載者:User
MD5簡介
MD5的全稱是Message-Digest Algorithm 5,在90年代初由MIT的電腦科學實驗室和RSA Data Security Inc發明,經MD2、MD3和MD4發展而來。

Message-Digest泛指位元組串(Message)的Hash變換,就是把一個任意長度的位元組串變換成一定長的大整數。請注意我使用了“位元組串”而不是“字串”這個詞,是因為這種變換隻與位元組的值有關,與字元集或編碼方式無關。

MD5將任意長度的“位元組串”變換成一個128bit的大整數,並且它是一個無法復原的字串變換演算法,換句話說就是,即使你看到來源程式和演算法描述,也無法將一個MD5的值變換回原始的字串,從數學原理上說,是因為原始的字串有無窮多個,這有點象不存在反函數的數學函數。

MD5的典型應用是對一段Message(位元組串)產生fingerprint(指紋),以防止被“篡改”。舉個例子,你將一段話寫在一個叫readme.txt檔案中,並對這個readme.txt產生一個MD5的值並記錄在案,然後你可以傳播這個檔案給別人,別人如果修改了檔案中的任何內容,你對這個檔案重新計算MD5時就會發現。如果再有一個第三方的認證機構,用MD5還可以防止檔案作者的“抵賴”,這就是所謂的數位簽章應用。

MD5還廣泛用於加密和解密技術上,在很多作業系統中,使用者的密碼是以MD5值(或類似的其它演算法)的方式儲存的,使用者Login的時候,系統是把使用者輸入的密碼計算成MD5值,然後再去和系統中儲存的MD5值進行比較,而系統並不“知道”使用者的密碼是什麼。

一些駭客破獲這種密碼的方法是一種被稱為“跑字典”的方法。有兩種方法得到字典,一種是日常搜集的用做密碼的字串表,另一種是用排列組合方法產生的,先用MD5程式計算出這些字典項的MD5值,然後再用目標的MD5值在這個字典中檢索。

即使假設密碼的最大長度為8,同時密碼只能是字母和數字,共26+26+10=62個字元,排列組合出的字典的項數則是P(62,1)+P(62,2)….+P(62,8),那也已經是一個很天文的數字了,儲存這個字典就需要TB級的磁碟組,而且這種方法還有一個前提,就是能獲得目標賬戶的密碼MD5值的情況下才可以。

在很多電子商務和社區應用中,系統管理使用者的Account是一種最常用的準系統,儘管很多Application Server提供了這些基本組件,但很多應用開發人員為了管理的更大的靈活性還是喜歡採用關聯式資料庫來系統管理使用者,懶惰的做法是使用者的密碼往往使用明文或簡單的變換後直接儲存在資料庫中,因此這些使用者的密碼對軟體開發人員或系統管理員來說可以說毫無保密可言,本文的目的是介紹MD5的Java Bean的實現,同時給出用MD5來處理使用者的Account密碼的例子,這種方法使得管理員和程式設計者都無法看到使用者的密碼,儘管他們可以初始化它們。但重要的一點是對於使用者密碼設定習慣的保護。

有興趣的讀者可以從這裡取得MD5也就是RFC 1321的文本。http://www.ietf.org/rfc/rfc1321.txt

實現策略


MD5的演算法在RFC1321中實際上已經提供了C的實現,我們其實馬上就能想到,至少有兩種用Java實現它的方法,第一種是,用Java語言重新寫整個演算法,或者再說簡單點就是把C程式改寫成Java程式。第二種是,用JNI(Java Native Interface)來實現,核心演算法仍然用這個C程式,用Java類給它包個殼。

但我個人認為,JNI應該是Java為瞭解決某類問題時的沒有辦法的辦法(比如與作業系統或I/O裝置密切相關的應用),同時為了提供和其它語言的互通性的一個手段。使用JNI帶來的最大問題是引入了平台的依賴性,打破了SUN所鼓吹的“一次編寫到處運行”的Java好處。因此,我決定採取第一種方法,一來和大家一起嘗試一下“一次編寫到處運行”的好處,二來檢驗一下Java 2現在對於比較密集的計算的效率問題。

實現過程


限於這篇文章的篇幅,同時也為了更多的讀者能夠真正專註於問題本身,我不想就某一種Java整合式開發環境來介紹這個Java Bean的製作過程,介紹一個方法時我發現步驟和命令很清晰,我相信有任何一種JavaIntegration Environment三天以上經驗的讀者都會知道如何把這些代碼在Integration Environment中編譯和運行。用Integration Environment講述問題往往需要配很多螢幕截圖,這也是我一直對Integration Environment很頭疼的原因。我使用了一個普通的文字編輯器,同時使用了Sun公司標準的JDK 1.3.0 for Windows NT。

其實把C轉換成Java對於一個有一定C語言基礎的程式員並不困難,這兩個語言的基本文法幾乎完全一致.我大概花了一個小時的時間完成了代碼的轉換工作,我主要作了下面幾件事:

把必須使用的一些#define的宏定義變成Class中的final static,這樣保證在一個進程空間中的多個Instance共用這些資料刪去了一些無用的#if define,因為我只關心MD5,這個推薦的C實現同時實現了MD2 MD3和 MD4,而且有些#if define還和C不同編譯器有關將一些計算宏轉換成final static 成員函數。
所有的變數命名與原來C實現中保持一致,在大小寫上作一些符合Java習慣的變化,計算過程中的C函數變成了private方法(成員函數)。
關鍵變數的位長調整定義了類和方法需要注意的是,很多早期的C編譯器的int類型是16 bit的,MD5使用了unsigned long int,並認為它是32bit的不帶正負號的整數。而在Java中int是32 bit的,long是64 bit的。在MD5的C實現中,使用了大量的位操作。這裡需要指出的一點是,儘管Java提供了位操作,由於Java沒有unsigned類型,對於右移位操作多提供了一個無符號右移:>>>,等價於C中的 >> 對於unsigned 數的處理。

因為Java不提供無符號數的運算,兩個大int數相加就會溢出得到一個負數或異常,因此我將一些關鍵變數在Java中改成了long類型(64bit)。我個人認為這比自己去重新定義一組無符號數的類同時重載那些運算子要方便,同時效率高很多並且代碼也易讀,OO(Object Oriented)的濫用反而會導致效率低下。

限於篇幅,這裡不再給出原始的C代碼,有興趣對照的讀者朋友可以去看RFC 1321。MD5.java原始碼

測試


在RFC 1321中,給出了Test suite用來檢驗你的實現是否正確:

MD5 ("") = d41d8cd98f00b204e9800998ecf8427e
MD5 ("a") = 0cc175b9c0f1b6a831c399e269772661
MD5 ("abc") = 900150983cd24fb0d6963f7d28e17f72
MD5 ("message digest") = f96b697d7cb7938d525a2f31aaf161d0
MD5 ("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b
……
這些輸出結果的含義是指:Null 字元串””的MD5值是d41d8cd98f00b204e9800998ecf8427e,字串”a”的MD5值是0cc175b9c0f1b6a831c399e269772661……
編譯並運行我們的程式:
javac –d . MD5.java
java beartool.MD5
為了將來不與別人的同名程式衝突,我在我的程式的第一行使用了package beartool;

因此編譯命令javac –d . MD5.java 命令在我們的工作目錄下自動建立了一個beartool目錄,目錄下放著編譯成功的 MD5.class

我們將得到和Test suite同樣的結果。當然還可以繼續測試你感興趣的其它MD5變換,例如:

java beartool.MD5 1234

將給出1234的MD5值。

可能是我的電腦知識是從Apple II和Z80單板機開始的,我對大寫十六進位代碼有偏好,如果您想使用小寫Digest String只需要把byteHEX函數中的A、B、C、D、E、F改成a、b、 c、d、e、f就可以了。

MD5據稱是一種比較耗時的計算,我們的Java版MD5一閃就算出來了,沒遇到什麼障礙,而且用肉眼感覺不出來Java版的MD5比C版的慢。

為了測試它的相容性,我把這個MD5.class檔案拷貝到我的另一台Linux+IBM JDK 1.3的機器上,執行後得到同樣結果,確實是“一次編寫到處運行了”。

[1] [2] [3] 下一頁  



相關文章

Alibaba Cloud 10 Year Anniversary

With You, We are Shaping a Digital World, 2009-2019

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。