2013-01-22 211 views
-3

在爲網站準備訪問數據時,我突然意識到由Java創建的MD5加密密碼與由PHP MD5創建的密碼完全不同。仔細查看這裏和其他地方的帖子,我發現了幾種Java解決方案,確保它們能夠提供與PHP完全相同的結果 - 但是所有的Java實現在它們之間提供了相同的結果,但是與PHP的結果完全不同。爲什麼Java MD5和PHP MD5提供完全不同的結果?

因此,我編寫了一個小型Java程序,它將相同的密碼發送到我的本地服務器以供PHP轉換,並且同時使用Java自行轉換它。這裏的程序:

public PHPDriver() { 
    String pwd = "aabbccdd"; 
    String p = encodeByPHP("http://localhost/testsite/md5.php?pwd=" + pwd); 
    System.out.println("PHPDriver:  " + pwd + " -> " + p); 

    System.out.println("md5:    " + pwd + " -> " + md5(p)); 
... 
public String encodeByPHP(String url) { 
    try { 
    // create a link to a URL 
    URL urlAddress = new URL(url); 
    URLConnection link = urlAddress.openConnection(); 
    BufferedReader inStream = new BufferedReader(new InputStreamReader(link.getInputStream())); 
    return inStream.readLine(); 
    } catch (MalformedURLException e) { 
... 
public String md5(String input) { 
    String result = input; 
    try { 
    if(input != null) { 
     MessageDigest md = MessageDigest.getInstance("MD5"); //or "SHA-1" 
     md.update(input.getBytes()); 
     BigInteger hash = new BigInteger(1, md.digest()); 
     result = hash.toString(16); 
     while(result.length() < 32) { 
     result = "0" + result; 
     } 
    } 
    } catch (NoSuchAlgorithmException nsa) { 

而且(絕大多數複雜;-) PHP頁面:

<?php 
    $pwd = $_GET['pwd']; 
    // echo $pwd . ' -> '; 
    echo sha1($pwd); 
?> 

這樣做的結果如下所示:

PHPDriver:  aabbccdd -> 527bee2730bf234e9a78bde5af091ece9c6302d5 
md5:    aabbccdd -> ab86815613f7f321001efef1935dbe7d 

什麼錯嗎?這是一個錯誤的編碼問題?爲什麼PHP的結果是40字符而不是通常的32?

+2

'sha1'不是'md5'。 – datasage

+5

它看起來像你的php代碼使用SHA1哈希算法,而你的java代碼使用MD5 ... –

+0

請注意輸出的* length * SHA-1是160位,20個字節,40個十六進制字符; MD5 128位,16個字節,32個十六進制字符。 – 2013-01-22 20:09:21

回答

4

你回來從你的PHP腳本

SHA1改用:

<?php 
    $pwd = $_GET['pwd']; 
    // echo $pwd . ' -> '; 
    echo md5($pwd); 
?> 
2

除了在其他的一個md5使用sha1,你不指定Charset當您在Java調用String.getBytes()。這可能會導致不可預知的行爲。指定類似UTF-8的Charset將得到一致的結果,然後您可以檢查PHP如何確保使用UTF-8對字符串進行散列處理。

+0

你應該總是指定字符編碼。但是如果你不這樣做,我不會說它*不可預測*如果您不指定字符編碼,則將使用系統的默認字符編碼。如果這與PHP使用的不同,結果顯然會有所不同。 – Jesper

+0

如果你將結果插入散列函數,並期望每次都得到相同的輸出,我會稱它爲一個真正的bug,而不是指定編碼。 –