2010-06-02 81 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哈希。