1

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

パスワードがphp5MD5に保存されている既存のユーザーデータベースを移行する必要がありました。私のJavaコードが正しいMD5ハッシュを生成しないため、すべてではなく一部のユーザーがログインできなくなりました。

上記の何が問題になっていますか?

4

4 に答える 4

10

byteArrToHexString<0x10のバイトは正しく変換されないため、ゼロで埋める必要があります。

例:

int unsigned = bArr[i] & 0xff;
if (unsigned < 0x10)
  sb.append("0");
sb.append(Integer.toHexString((unsigned)));
于 2009-06-29T07:51:18.220 に答える
1

とても面白い...MD5ハッシュパスワードで問題が発生しました。私の場合の問題は、元のパスワードをにエンコードすることでしたbyte[]

以前にパスワードをハッシュするために使用されたエンコーディングを正確に調べ、上記のコードの6行目を次のように変更することをお勧めします。

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

(もちろん、これは単なる例です...パラメータとして使用する正しい文字セットを見つけてください)

ところで、あなたには理由があると思いますが、ハッシュメソッドにこれを行わせてみませんか?

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

ユヴァル=8-)

于 2009-06-29T08:06:38.783 に答える
0

あなたが行方不明です:

md5.reset();

update()を実行する前に

MessageDigestでJavamd5の例を確認してください

于 2009-06-29T07:50:49.860 に答える
0

私は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いくつかのベンチマークによると、この関数は関数の約2倍高速であると言え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'
于 2019-08-17T19:48:53.160 に答える