Java 和 php5 MD5 哈希之间的区别

发布于 2024-07-25 21:09:55 字数 872 浏览 4 评论 0原文

我面临着一个奇怪的问题,它与 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 哈希值。

有什么想法以上有什么问题吗?

I'm facing kind of a strange issue which is related MD5-Hashes in Java and php5.
I figured that unter certain circumstances the following code does not
generate correct MD5 hashes:

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

I had to migrate an existing user database where the passwords where stored
in php5 MD5. Now some of the users, not all, can't login because my Java code
does not produce the correct MD5 hash.

Any ideas what's wrong with the above?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

嘿嘿嘿 2024-08-01 21:09:55

byteArrToHexString 无法正确转换 <0x10 的字节,您需要用零填充它们。

例子:

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

byteArrToHexString does not convert bytes <0x10 correctly, you need to pad them with zeros.

Example:

int unsigned = bArr[i] & 0xff;
if (unsigned < 0x10)
  sb.append("0");
sb.append(Integer.toHexString((unsigned)));
偏爱自由 2024-08-01 21:09:55

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

我建议您确切地找出之前使用哪种编码来哈希密码,并将上面代码的第6行更改为

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

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

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

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

尤瓦尔=8-)

So funny... I just encountered a problem with MD5 hashed passwords myself. The problem in my case was the encoding of the original password into a byte[].

I advise you to find out exactly which encoding was used to hash the passwords previously, and change line 6 of the code above to

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

(Of course, this is just an example... find out the correct Charset to use as a parameter)

BTW, I suppose you have your reasons, but why not have the hashing method do this?

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

Yuval =8-)

凉风有信 2024-08-01 21:09:55

您缺少:

md5.reset();

在执行 update() 之前

检查 Java带有 MessageDigest 的 md5 示例

You are missing:

md5.reset();

before doing an update()

Check Java md5 example with MessageDigest

水染的天色ゝ 2024-08-01 21:09:55

我找到了 2 个解决方案(从此处找到 和其他答案):

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'

I've found 2 solutions (found from here and from the other answers) :

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")
    }
}

According to some benchmarks, I can say that the md5 function is about twice faster than the md5Hex function. Here's the test:

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 file has this:

implementation 'org.apache.commons:commons-lang3:3.7'
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文