2012-01-04 69 views
2

我正在使用以下代碼來散列傳入的字符串,期望多次應用於該方法的相同的東西總是會得到相同的結果。該場景將用於密碼散列和稍後驗證。但它似乎並不奏效 - 我爲同一個輸入字符串得到了兩個不同的blob。我的代碼有什麼不對嗎?SHA將相同的字符串散列到不同的塊中

public synchronized String encrypt(String token) { 
    try { 
     MessageDigest sha = MessageDigest.getInstance("SHA"); 
     sha.reset(); 
     sha.update(token.getBytes("UTF-8")); 
     byte[] raw = sha.digest(); 
     System.out.println("raw = " + raw.toString()); 
     String hash = Base64.encodeBase64(raw).toString(); 
     return hash; 
    } catch (Exception e) { 
    } 

    return token; 
} 
+0

添加相關語言的標籤。我相信你忘了添加'Java'。 – 2012-01-04 18:01:55

+0

謝謝,補充一下。 – tom 2012-01-04 18:03:14

+0

SHA是** NOT **加密。 – Dan 2012-01-04 18:04:28

回答

5

你真的沒有給予足夠的信息,但我懷疑你被分心本:

System.out.println("raw = " + raw.toString()); 

那將打印出像[[email protected]具有沒有做的東西字節數組中的數據。你應該打印出hash而不是 - 如果你的token真的是一樣的,那麼應該是對於所有呼叫都是相同的。

(正如丹指出,你的方法不當命名爲:哈希是不加密的同時,請不要趕Exception剛嚥下這樣的例外似乎很奇怪,剛剛在失敗時返回token,。 )

編輯:如上所述,我假設Base64.encode實際上返回一個字符串,它可能不會。我建議this base64 implementation這是公共領域,並有一個合理的API - 編碼調用返回一個字符串,這是完全合適的。當然,你不需要明確的toString()調用以及...

+0

感謝您的收穫!什麼是真正的加密所需的額外步驟?我的代碼是根據一些說密碼加密的示例代碼編寫的。 – tom 2012-01-04 18:13:29

+1

@tom:對於密碼,您可能*不應該使用可逆加密。即使散列本身並不好 - 你至少應該對散列進行加鹽,以及選擇合適的散列算法。 (做更多細節的搜索salt hash加密。) – 2012-01-04 18:21:19

+0

非常感謝解釋。 – tom 2012-01-04 18:28:40

1

我不知道你使用的是什麼Base64類,但我將假設來自Apache Commons。你這樣做:

String hash = Base64.encodeBase64(raw).toString(); 

這是調用任何隨機字節數組的toString方法是從Base64.encodeBase64()方法返回。這就是爲什麼你的結果每次都是隨機的,你只是以String的形式返回一個對象引用。試試這個:

String hash = Base64.encodeBase64String(raw); 

編輯

正如在另一篇文章中指出,直接轉換爲字符串可能是一個壞主意。我稍微編輯了我的答案以反映這一點。

相關問題