計算 位元組陣列、字串與檔案的 MessageDigest 值 (MD5、SHA-1、SHA-256…)

  • 23197
  • 0

計算 位元組陣列、字串與檔案的 MessageDigest 值 (MD5、SHA-1、SHA-256…)

Message Digest 中文是「訊息摘要」,就是將訊息透過特別的演算法計算,得到一組可以代表這段訊息的特徵值。

簡單來說,就類似每個人身上都有不同的指紋,而指紋就是這個人的特徵。

而常見的 Message Digest 演算法,包含: MD5SHA-1

MD5 算出來的 Message Digest 是一串 128 bits 的訊息摘要,所以有 2^128 種組合;

SHA-1 算出來的 Message Digest 是一串 160 bits 的訊息摘要,所以有 2^160 種組合。

由於 Message Digest 演算法 (1) 計算時間很快 (2) 同一訊息特徵值都相同,所以常常拿來應用。

例如:拿來當 (1) 密碼 與 SaltedString 的驗證 (2) 檔案下載的封包 checksum 驗證。

 

題外話,雖然 2005年「王小雲」已經找到「破解」MD5 與 SHA-1 的方法,但只是縮短碰撞時率的時間。

能夠讓 MD5 與 SHA-1 快速地找到 Message 本文,但是離破解密碼還有一段距離。

 

而之前艾小克「取得 MD5 (SHA1) 的三種方法」文章,談到 .Net 計算兩種 MessageDigest 的方法。

而本篇文篇範例,則是介紹使用 Java 來計算 位元組陣列、字串、檔案 的 MessageDigest 值。

目前在 Java SDK 6.0 中主要支援 MessageDigest Algorithm 有六種,

包含:MD2、MD5、SHA-1、SHA-256、SHA-384、SHA-512 在本篇範例中都會一一展示。

 

 


 

我們就直接看程式碼:

螢幕快照 2011-01-18 下午5.59.17

 

第 17 行,利用 MessageDigest.getInstance() 方法建立一個  MessageDigest 物件 messageDigest。

algorithm 參數則如同前言所提,包含以下六種:MD2、MD5、SHA-1、SHA-256、SHA-384、SHA-512

 

第 25 行,則是利用 MessageDigest 物件 messageDigest 的 update() 方法,計算 byte[] 物件 buffer 的 Message Digest 值。

 

第 26 行,則是利用 MessageDigest 物件 messageDigest 的 digest() 方法,取得 Message Digest 值,該值是以 byte[] 儲存。

 

第 28 – 33 行,則是迴圈計算每一個 byte 值,將每個 byte 值轉為 hex 字串表示。

 

 


 

1. 位元組陣列 的 MessageDiagest:

透過剛剛介紹自定 calculateMessagesDigest() 方法,我們就可以寫一個 getMessagesDigest() 方法,提供我們來方便地呼叫:

螢幕快照 2011-01-18 下午6.00.06

 

第 51 – 57 行,則是 algorithm 字串變數與內建的演算法做不分大小寫的字串比對,

如果是 Java 有支援的演算法才將 byte[] 型態 data 變數傳入剛剛 calculateMessagesDigest() 計算 MessageDigest hex 字串值。

 

2. 字串的 MessageDiagest:

螢幕快照 2011-01-18 下午6.03.32

第 40 – 46 行,則是 algorithm 字串變數與內建的演算法做不分大小寫的字串比對,

比較不同的是,我們必須將字串轉 byte[] 才能呼叫 calculateMessagesDigest() 方法,所以我們使用內建的字串物件 getBytes() 方法即可。

(如果有 Encoding 的問題,則帶入多載的 getBytes() 方法,傳入不同的 Charset 物件)

 

3. 檔案的 MessageDiagest:

螢幕快照 2011-01-18 下午6.00.40

 

由於 calculateMessagesDigest() 方法需要的參數是 byte[],所以我們比較將檔案轉換成 byte[]。

所以,第 62 行將 filePath 與 fileName 字串連接在一起,並建立 File 物件 file。

 

第 66 行,則是透過 File 物件 file 轉為 FileInputStream 物件 fis。

 

第 74 – 79 行,則是將 FileInputStream 物件 fis 的 byte[] 內容讀出並放入 byte[] 變數 data 中。

 

第 86 – 92 行,則是 algorithm 字串變數與內建的演算法做不分大小寫的字串比對,

將 byte[] 型態 data 變數傳入剛剛 calculateMessagesDigest() 計算 MessageDigest hex 字串值。

 

 


 

剛剛我們建立三個 getMessagesDigest() 多載的方法,現在我們就可以來測試使用:

螢幕快照 2011-01-18 下午5.58.43

 

第 17 行,我們建立一個字串陣列  algorithmsStrings ,儲存 Java 所有支援的 Message Digest 演算法。

 

第 19 –25 行,我們使用 for 迴圈去尋覽所有的 algorithmsStrings 字串值,並呼叫三個 getMessagesDigest() 多載的方法:

第 21 行,我們帶入不同的演算法,利用字串常數 “a”計算不同的 Message Digest 值。

第 22 行,我們帶入不同的演算法,利用 常數位元組陣列  97 (其實就是 a 的 ASCII碼) 計算不同的 Message Digest 值。

第 23 行,我們帶入不同的演算法,利用 檔案  /User/chhuang/Desktop 路徑下的 untitled.txt (其實內容只有 “a”) 計算不同的 Message Digest 值。

 

執行結果如下:

MD2 string : 32ec01ec4a6dac72c0ab96fb34c0b5d1
MD2 byte[] : 32ec01ec4a6dac72c0ab96fb34c0b5d1
MD2 file   : 32ec01ec4a6dac72c0ab96fb34c0b5d1

MD5 string : 0cc175b9c0f1b6a831c399e269772661
MD5 byte[] : 0cc175b9c0f1b6a831c399e269772661
MD5 file   : 0cc175b9c0f1b6a831c399e269772661

SHA-1 string : 86f7e437faa5a7fce15d1ddcb9eaeaea377667b8
SHA-1 byte[] : 86f7e437faa5a7fce15d1ddcb9eaeaea377667b8
SHA-1 file   : 86f7e437faa5a7fce15d1ddcb9eaeaea377667b8

SHA-256 string : ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb
SHA-256 byte[] : ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb
SHA-256 file   : ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb

SHA-384 string : 54a59b9f22b0b80880d8427e548b7c23abd873486e1f035dce9cd697e85175033caa88e6d57bc35efae0b5afd3145f31
SHA-384 byte[] : 54a59b9f22b0b80880d8427e548b7c23abd873486e1f035dce9cd697e85175033caa88e6d57bc35efae0b5afd3145f31
SHA-384 file   : 54a59b9f22b0b80880d8427e548b7c23abd873486e1f035dce9cd697e85175033caa88e6d57bc35efae0b5afd3145f31

SHA-512 string : 1f40fc92da241694750979ee6cf582f2d5d7d28e18335de05abc54d0560e0f5302860c652bf08d560252aa5e74210546f369fbbbce8c12cfc7957b2652fe9a75
SHA-512 byte[] : 1f40fc92da241694750979ee6cf582f2d5d7d28e18335de05abc54d0560e0f5302860c652bf08d560252aa5e74210546f369fbbbce8c12cfc7957b2652fe9a75
SHA-512 file   : 1f40fc92da241694750979ee6cf582f2d5d7d28e18335de05abc54d0560e0f5302860c652bf08d560252aa5e74210546f369fbbbce8c12cfc7957b2652fe9a75