2012-01-04 29 views
4

我正在創建一個簡單的Web應用程序,並希望將散列的密碼存儲到數據庫中。我也需要驗證令牌的散列函數(連接用戶名和日期,並將它們的散列作爲令牌發送給客戶端)。通過MessageDigest瞭解Java中的哈希密碼

我發現MessageDigest Java類可以幫助我解決這個問題。 Here is one link。 的基本思路是這樣的:

public String digestString (String stringToHash) throws NoSuchAlgorithmException { 
    MessageDigest sha256 = MessageDigest.getInstance("SHA-256");   
    byte[] stringBytes = stringToHash.getBytes(); 
    byte[] stringDigest = sha256.digest(stringBytes); 
    return new String(stringDigest); 
} 

我不明白的是: 在這段代碼中,我怎麼能設置散列鍵?我需要確保在驗證過程中使用相同的密鑰。如果我不設置密鑰,我該怎麼做?

順便說一句:我知道我應該添加一個鹽(在這種情況下是256字節)散列文本之前散列它。

+0

你是什麼意思的散列「鑰匙」?如果你的意思是像HMAC這樣的事情,那麼必須在前一步中完成,然後來自該輸出的字節將被送入'MessageDigest'方法。 MessageDigest只是散列一個字節數組而不考慮其內容。 – Peter 2012-01-04 18:36:13

+0

@Peter:實際上java有一個Mac類,Oracle提供者實現HMAC,例如'Mac hmac = Mac.getInstance('HmacSHA1');'工作。 – 2012-01-05 01:26:53

回答

7

散列不使用密鑰。這只是一種單向算法。你給它一些消化,並返回一個散列。它所保證的是,很難找到導致相同散列的原始輸入或任何其他輸入。

你的算法有兩個基本問題(除了缺乏醃製的):

  • 它使用String.getBytes(),它依賴於默認的平臺編碼,從而從不同的平臺與平臺。您應該指定一個編碼,如UTF-8。
  • 它使用新的String(byte []),它有與上面相同的問題+另外一個:所有的字節序列都不是有效的字符。要將純二進制字節數組轉換爲字符串,請使用base64編碼算法。 Apache公共代碼有一個。
+0

謝謝大家的回答。我只是意識到這個過程對於密碼來說是很好的。它對身份驗證令牌不好...我必須使用隱藏於身份驗證令牌的密鑰。 – 2012-01-05 10:54:02