有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java和php5 MD5哈希之间的php差异

我面临一个奇怪的问题,它与Java和php5中的MD5哈希有关。 我认为在某些情况下,下面的代码不会 生成正确的MD5哈希:

public static String getMD5Hash(String string)
{
    try 
    {
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        md5.update(string.getBytes());
        byte[] digest = md5.digest();

        string = byteArrToHexString(digest);
    } 
    catch (NoSuchAlgorithmException e1) 
    {
        e1.printStackTrace();
    }

    return string;
}

private static String byteArrToHexString(byte[] bArr)
{
    StringBuffer sb = new StringBuffer();

    for (int i = 0; i < bArr.length; i++) 
    {
        int unsigned = bArr[i] & 0xff;
        sb.append(Integer.toHexString((unsigned)));
    }

    return sb.toString();
}

我必须迁移一个现有的用户数据库,其中存储了密码 在php5-MD5中。现在,有些用户(不是所有用户)无法登录,因为我的Java代码 未生成正确的MD5哈希

你知道上面有什么问题吗


共 (4) 个答案

  1. # 1 楼答案

    byteArrToHexString不转换字节<;0x10正确,您需要用零填充它们

    例如:

    int unsigned = bArr[i] & 0xff;
    if (unsigned < 0x10)
      sb.append("0");
    sb.append(Integer.toHexString((unsigned)));
    
  2. # 2 楼答案

    真有趣。。。我自己刚刚遇到了MD5哈希密码的问题。我的问题是将原始密码编码为byte[]

    我建议您准确地找出以前用于散列密码的编码,并将上面代码的第6行更改为

    md5.update(string.getBytes("UTF-8"));
    

    (当然,这只是一个示例……找出要用作参数的正确字符集)

    顺便说一句,我想你有你的理由,但为什么不让散列方法这样做呢

    return new String(digest, "UTF-8");
    

    Yuval=8-)

  3. # 4 楼答案

    我找到了两个解决方案(从here和其他答案中找到):

    object MD5Util {
        private val messageDigest: MessageDigest?
    
        init {
            val testMd =
                    try {
                        MessageDigest.getInstance("MD5")
                    } catch (e: Exception) {
                        null
                    }
            messageDigest = testMd
        }
    
        private fun hex(array: ByteArray): String {
            val sb = StringBuilder()
            for (b in array)
                sb.append(Integer.toHexString((b.toInt() and 0xFF) or 0x100).substring(1, 3))
            return sb.toString()
        }
    
        @JvmStatic
        fun md5Hex(message: String): String {
            if (messageDigest != null)
                try {
                    return hex(messageDigest.digest(message.toByteArray(charset("CP1252"))))
                } catch (e: Exception) {
                    throw e
                }
            throw Exception("messageDigest not found")
        }
    
        @JvmStatic
        fun md5(s: String): String {
            if (messageDigest != null)
                try {
                    val hash: ByteArray = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
                        messageDigest.digest(s.toByteArray(StandardCharsets.UTF_8))
                    else
                        messageDigest.digest(s.toByteArray(charset("UTF-8")))
                    val sb = StringBuilder()
                    for (aHash in hash) {
                        val hex = Integer.toHexString(aHash.toInt())
                        if (hex.length == 1)
                            sb.append('0').append(hex[hex.length - 1])
                        else
                            sb.append(hex.substring(hex.length - 2))
                    }
                    return sb.toString()
                } catch (e: Exception) {
                    throw e
                }
            throw Exception("messageDigest not found")
        }
    }
    

    根据一些基准测试,我可以说md5函数的速度大约是md5Hex函数的两倍。以下是测试:

    class MainActivity : AppCompatActivity() {
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
            AsyncTask.execute {
                val emailList=ArrayList<String>()
                for (i in 0 until 100000)
                    emailList.add( generateRandomEmail(10))
                var startTime = System.currentTimeMillis()
                for (email in emailList)
                    MD5Util.md5(email)
                var endTime = System.currentTimeMillis()
                Log.d("AppLog", "md5 - time taken: ${endTime - startTime}")
                startTime = System.currentTimeMillis()
                for (email in emailList)
                    MD5Util.md5Hex(email)
                endTime = System.currentTimeMillis()
                Log.d("AppLog", "md5Hex - time taken: ${endTime - startTime}")
            }
        }
    
        companion object {
            private const val ALLOWED_CHARS = "abcdefghijklmnopqrstuvwxyz" + "1234567890" + "_-."
    
            @Suppress("SpellCheckingInspection")
            fun generateRandomEmail(@IntRange(from = 1) localEmailLength: Int, host: String = "gmail.com"): String {
                val firstLetter = RandomStringUtils.random(1, 'a'.toInt(), 'z'.toInt(), false, false)
                val temp = if (localEmailLength == 1) "" else RandomStringUtils.random(localEmailLength - 1, ALLOWED_CHARS)
                return "$firstLetter$temp@$host"
            }
        }
    }
    

    gradle文件包含以下内容:

    implementation 'org.apache.commons:commons-lang3:3.7'