2012-11-30 40 views
5

我腦海中的某個東西告訴我我錯過了一些明顯的東西。MessageDigest MD5算法沒有返回我期望的結果

我正在使用api密鑰的md5哈希進行身份驗證的第三方API集成了現有的Java項目。它不適合我,在調試過程中,我意識到我生成的哈希表與他們提供的示例不匹配。我發現一些網站可以通過字符串創建MD5哈希來檢查他們的例子,並且據我所知,我錯了,他們是對的。

例如,根據this website,字符串「hello」生成「5d41402abc4b2a76b9719d911017c592」的散列。 (FWIW我對這個網站一無所知,只是它似乎正確地散列了我所擁有的例子)。當我通過我的代碼運行它,我得到:

XUFAKrxLKna5cZ2REBfFkg ==

下面是一個簡單的方法,我用生成MD5哈希/串:

private String md5(String md5Me) throws Exception { 
    MessageDigest md = MessageDigest.getInstance("MD5"); 
    md.reset(); 
    md.update(md5Me.getBytes("UTF-8")); 

    return Base64.encodeBase64String(md.digest()); 
} 

我用了一個很類似的方法可以在上週使用SHA1算法成功驗證不同的API。我想知道如果問題是相關的org.apache.commons.net.util.Base64.encodeBase64String ...任何幫助非常感謝,如果只有一些測試,看看如果byteArray是正確的,但轉換的字符串是錯誤的。

+1

md.digest()應該包含您正在查找的字節,您使用Base64算法進一步對它們進行編碼並獲得不同的結果 – hoaz

+0

我需要將這些字節轉換爲http請求的字符串,是否有更好的方法可以做到這一點? – eric

+1

新的字符串(字節[]字節) – Andy

回答

8

例如,根據本網站時,字符串 「hello」 生成 「5d41402abc4b2a76b9719d911017c592」 的散列。 (FWIW我對這個網站一無所知,只是它似乎正確地散列了我所擁有的例子)。當我通過我的代碼運行它,我得到:

XUFAKrxLKna5cZ2REBfFkg ==

兩者都代表相同的十六字節散列的正確途徑。 5d41402abc4b2a76b9719d911017c592將散列的每個字節表示爲兩個十六進制數字,而XUFAKrxLKna5cZ2REBfFkg==使用Base-64來表示每個三個字節的散列,因爲四個個字符。

要生成的十六進制版本,這個第三方API期待,你可以改變這一點:

Base64.encodeBase64String(md.digest()); 

這樣:

String.format("%032x", new BigInteger(1, md.digest())); 

(主要來自this StackOverflow answer拍攝)。

但是,您可能需要考慮使用外部庫。 Perception,在上面的評論中提到了Apache Commons DigestUtils。如果你使用它,你需要the md5hex method

+0

將它標記爲正確,因爲它解決了我的問題,解釋了究竟發生了什麼,並引用了Perception的關於使用DigestUtils(也適用)的建議。謝謝! – eric

+0

@eric:不客氣! – ruakh

2

md5哈希算法是核心java API的一部分,因此不需要任何外部庫。以下是我用MD5加密密碼的方法。

import java.security.MessageDigest; 

/** 
* Use to encrypt passwords using MD5 algorithm 
* @param password should be a plain text password. 
* @return a hex String that results from encrypting the given password. 
*/ 
public static String encryptPassword(String password) { 
    try { 
     MessageDigest md = MessageDigest.getInstance("MD5"); 
     md.update(password.getBytes()); 

     byte byteData[] = md.digest(); 

     StringBuffer hexString = new StringBuffer(); 
     for (int i=0;i<byteData.length;i++) { 
      String hex=Integer.toHexString(0xff & byteData[i]); 
      if(hex.length()==1) hexString.append('0'); 
      hexString.append(hex); 
     } 
     return hexString.toString(); 
    } 
    catch(java.security.NoSuchAlgorithmException missing) { 
     return "Error."; 
    } 
}