【问题标题】:convert password encryption from java to php将密码加密从java转换为php
【发布时间】:2011-02-26 18:33:50
【问题描述】:

我正在尝试创建现有 JSP 程序的 PHP 版本,但是我被困在密码加密部分。

你能告诉我如何转换这个吗?我知道它试图获取 md5() 但在那之后,我不明白了。我迷失在 Stringbuffer 和 for() 部分。

你能帮帮我吗?

 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; 
 }

【问题讨论】:

  • 仅供参考(我相信你已经知道了),这不是加密,而是散列。 :)
  • 是的,我也想知道为什么这个函数被称为 encryptPassword :P
  • @Obay 在问题标题中:“密码加密”。

标签: java php encryption passwords md5


【解决方案1】:

为了在 java 和 php 中获得相同的结果,我使用了这个。

Java(确保在“try”块中调用方法):

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 哈希。

【讨论】:

    【解决方案2】:
    <?php
    $password = "MyPass";
    $hash = md5($password);
    ?>
    

    更新: 两个版本之间存在一些差异。要解决此问题,请参阅@bobince 答案。这是测试代码:

    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
    

    【讨论】:

    • 似乎不只是一个 md5() 因为我检查了数据库中生成的密码,它们不是 32 个字符。长度范围从 29 到 32..
    • 老兄,pass1 和 pass3 不一样。 java的pass1去掉了一个零。 java的pass3去掉了第一个零。
    【解决方案3】:

    伊拉克利斯应该是对的。 md5() 默认为您提供十六进制编码的输出字符串。您只能通过为可选的$raw_output 参数传入TRUE 来获得Java 中未编码的字节。

    长度范围从 29 到 32

    那么您的 Java 代码有错误。 MD5 哈希值始终为 128 位(32 个十六进制数字)。这里是:

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

    这将为低于 16 的所有字节生成 1 而不是 01。您存储的是一个损坏的哈希,您无法从中恢复原始 MD5 值。如果您绝对必须保留这些损坏的数据,则必须在 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;
    }
    

    【讨论】:

    • bobince,当场,刚刚测试它会产生损坏的 Java 哈希。
    【解决方案4】:

    它将 MD5 哈希转换为字符的最低有效字节的十六进制数字字符串。在 Java 中,所有字符都是 2 个字节。

    实际上,这仅表示 ASCII 值。

    【讨论】:

    • 在 PHP 中到底是什么意思?是否对从 md5 生成的每个字符调用 md5() 然后调用 ord()?
    • 我猜 bin2hex(md5(password,true)) 应该接近
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-05
    • 1970-01-01
    • 1970-01-01
    • 2013-06-23
    • 1970-01-01
    • 2017-07-24
    • 2019-06-06
    相关资源
    最近更新 更多