2010-06-02 77 views
-1

我正在嘗試創建現有JSP程序的PHP版本,但是我被卡在密碼加密部分。將密碼加密從java轉換爲php

你能告訴我如何轉換這一個嗎?我知道它試圖獲得md5(),但之後,我不明白。我迷失在Stringbuffer和()部分。

你能幫我嗎?

public static String encryptPassword(String password) 
{ 
    String encrypted = ""; 
    try 
    { 
     MessageDigest digest = MessageDigest.getInstance("MD5"); 
     byte[] passwordBytes = password.getBytes(); 

     digest.reset(); 
     digest.update(passwordBytes); 
     byte[] message = digest.digest(); 

     StringBuffer hexString = new StringBuffer(); 
     for (int i=0; i < message.length; i++) 
     { 
      hexString.append(Integer.toHexString(
       0xFF & message[ i ])); 
     } 
     encrypted = hexString.toString(); 
    } 
    catch(Exception e) { } 
    return encrypted; 
} 
+1

只是FYI(我相信你已經知道,)它不是加密,它是散列。 :) – 2010-06-02 11:28:37

+0

是的,我也想知道爲什麼該函數被稱爲encryptPassword:P – Obay 2010-06-02 11:44:16

+0

@Obay在問題標題:「密碼加密」。 – zaph 2016-03-01 22:07:27

回答

3

伊拿克里斯應對。 md5()默認爲您提供十六進制編碼的輸出字符串。您只能通過傳入TRUE來獲得可選的$raw_output參數,從而像Java那樣獲得未編碼的字節。

長度範圍從29到32

那麼你的Java代碼中有一個錯誤。 MD5散列總是128位(32位十六進制數字)。那就是:

hexString.append(Integer.toHexString(0xFF & message[ i ])); 

這將產生1而不是01低於16.所有字節什麼已存儲是一種錯位的哈希,從中您將無法恢復原來的MD5值。如果你絕對必須保持這個破碎的數據,你將不得不重現bug在PHP中:

function makeBrokenMD5($s) { 
    $hash= md5($s, TRUE); 
    $bytes= preg_split('//', $hash, -1, PREG_SPLIT_NO_EMPTY); 
    $broken= ''; 
    foreach ($bytes as $byte) 
     $broken.= dechex(ord($byte)); 
    return $broken; 
} 
+0

bobince,現場,剛剛測試它產生了破碎的Java哈希。 – Iraklis 2010-06-02 11:32:07

1

它將MD5散列轉換爲字符的最小有效字節的字符串十六進制數字。在Java中,所有字符都是2個字節。

實際上這意味着只有ASCII值。

+0

它在PHP中意味着什麼?它是調用一個md5()然後一個ord()從每個字符生成的MD5? – Obay 2010-06-02 11:12:54

+0

我猜bin2hex(md5(密碼,真))應該接近 – 2010-06-02 11:22:45

1
<?php 
$password = "MyPass"; 
$hash = md5($password); 
?> 

更新: 這兩個版本之間有一些差異。爲了解決這個問題看@bobince answer.Here是測試代碼:

的Java

package tests; 

import java.security.MessageDigest; 

/** 
* Created by IntelliJ IDEA. 
* User: Iraklis 
* Date: 2 Ιουν 2010 
* Time: 2:15:03 μμ 
* To change this template use File | Settings | File Templates. 
*/ 
public class Md5Test { 
    public static String encryptPassword(String password) { 
     String encrypted = ""; 
     try { 
      MessageDigest digest = MessageDigest.getInstance("MD5"); 
      byte[] passwordBytes = password.getBytes(); 

      digest.reset(); 
      digest.update(passwordBytes); 
      byte[] message = digest.digest(); 

      StringBuffer hexString = new StringBuffer(); 
      for (int i = 0; i < message.length; i++) { 
       hexString.append(Integer.toHexString(
         0xFF & message[i])); 
      } 
      encrypted = hexString.toString(); 
     } 
     catch (Exception e) { 
     } 
     return encrypted; 
    } 

    public static void main(String[] args) { 
     System.out.println("Pass1 md5 = " + encryptPassword("Test123FORXTREMEpass")); 
     System.out.println("Pass1 md5 = " + encryptPassword("Ijdsaoijds")); 
     System.out.println("Pass1 md5 = " + encryptPassword("a")); 
     System.out.println("Pass1 md5 = " + encryptPassword(" ")); 
    } 

} 


Output: 
Pass1 md5 = dc3a7b42a97a3598105936ef22ad2c1 
Pass1 md5 = df7ca542bdbf7c4b8776cb21c45e7eef 
Pass1 md5 = cc175b9c0f1b6a831c399e269772661 
Pass1 md5 = 7215ee9c7d9dc229d2921a40e899ec5f 

PHP

<?php 
echo "Pass1 md5 = ".md5("Test123FORXTREMEpass")."<BR>"; 
echo "Pass2 md5 = ".md5("Ijdsaoijds")."<BR>"; 
echo "Pass3 md5 = ".md5("a")."<BR>"; 
echo "Pass4 md5 = ".md5(" ")."<BR>"; 
?> 

輸出:

Pass1 md5 = dc3a7b42a97a35981059036ef22ad2c1 
Pass2 md5 = df7ca542bdbf7c4b8776cb21c45e7eef 
Pass3 md5 = 0cc175b9c0f1b6a831c399e269772661 
Pass4 md5 = 7215ee9c7d9dc229d2921a40e899ec5f 
+0

似乎不只是一個md5(),因爲我檢查了數據庫中生成的密碼,他們不是32個字符。長度範圍從29到32 .. – Obay 2010-06-02 11:11:53

+0

Java輸出顯然是錯誤的,它缺少一些'0'。 – bobince 2010-06-02 11:29:22

+0

老兄,pass1和pass3是不一樣的。 java的pass1已經刪除了一個零。 java的pass3已經刪除了第一個零。 – Obay 2010-06-02 11:29:58

0

要獲得在Java相同的結果和php我用這個。

的Java(請確保調用一個 「嘗試」 塊內的方法):

public static String getHash(String pass) throws Exception 
{ 
    MessageDigest md=MessageDigest.getInstance("MD5"); 
    md.update(pass.getBytes(),0,pass.length()); 
    return new BigInteger(1,md.digest()).toString(16); 
} 

PHP:

<?php 
echo md5(pass); 
?> 

希望這有助於

編輯:如果Java變種回報31個字符,在字符串前添加一個「0」以匹配返回32個字符的PHP哈希。