Java's MessageDigest SHA1-algorithm returns different result than SHA1-function of php

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-17 16:21:25

问题


I have a SQL table with usernames and passwords. The passwords are encoded using MessageDigest's digest() method. If I encode a password - let's say "abcdef12" - with MessageDigest's digest() method and then convert it to hexadecimal values, the String is different than if I do the same using PHP's SHA1-method. I'd expect these values to be exactly the same though.

Code that is used to encode the passwords:

MessageDigest md = MessageDigest.getInstance("SHA-1");
byte[] passbyte;
passbyte = "abcdef12".getBytes("UTF-8");
passbyte = md.digest(passbyte);

The conversion of the String to hexadecimal is done using this method:

public static String convertStringToHex(String str) {

    char[] chars = str.toCharArray();

    StringBuffer hex = new StringBuffer();
    for (int i = 0; i < chars.length; i++) {
        hex.append(Integer.toHexString((int) chars[i]));
    }

    return hex.toString();
}

Password: abcdef12

Here's the password as returned by a lot of SHA1-hash online generators and PHP SHA1()-function: d253e3bd69ce1e7ce6074345fd5faa1a3c2e89ef

Here's the password as encoded by MessageDigest: d253e3bd69ce1e7ce674345fd5faa1a3c2e2030ef

Am I forgetting something?

Igor.

Edit: I've found someone with a similar problem: C# SHA-1 vs. PHP SHA-1...Different Results? . The solution was to change encodings.. but I can't change encodings on the server-side since the passwords in that SQL-table are not created by my application. I use client-side SHA1-encoding using a JavaScript SHA1-class (more precisely: a Google Web Toolkit-class). It works and encodes the string as expected, but apparently using ASCII characters?..


回答1:


It has nothing to do with the encodings. The output would be entirely different.

For starters, your function convertStringToHex() doesn't output leading zeros, that is, 07 becomes just 7.

The rest (changing 89 to 2030) is also likely to have something to do with that function. Try looking at the value of passbyte after passbyte = md.digest(passbyte);.




回答2:


I have the same digest as PHP with my Java SHA-1 hashing function:

public static String computeSha1OfString(final String message) 
    throws UnsupportedOperationException, NullPointerException {
        try {
               return computeSha1OfByteArray(message.getBytes(("UTF-8")));
        } catch (UnsupportedEncodingException ex) {
                throw new UnsupportedOperationException(ex);
        }
}

private static String computeSha1OfByteArray(final byte[] message)
    throws UnsupportedOperationException {
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-1");
            md.update(message);
            byte[] res = md.digest();
            return toHexString(res);
        } catch (NoSuchAlgorithmException ex) {
            throw new UnsupportedOperationException(ex);
        }
}

I've added to my unit tests:

String sha1Hash = StringHelper.computeSha1OfString("abcdef12");
assertEquals("d253e3bd69ce1e7ce6074345fd5faa1a3c2e89ef", sha1Hash);

Full source code for the class is on github.




回答3:


Try this - it is working for me:

MessageDigest md = MessageDigest.getInstance(algorithm);
md.update(original.getBytes());
byte[] digest = md.digest();
StringBuffer sb = new StringBuffer();
for (byte b : digest) {
    sb.append(Integer.toString((b & 0xff) + 0x100, 16).substring(1));
}
return sb.toString();

Regards, Konki




回答4:


Or try this:

MessageDigest md = MessageDigest.getInstance("SHA-1");
md.update(clearPassword.getBytes("UTF-8"));
return new BigInteger(1 ,md.digest()).toString(16));

Cheers Roy



来源:https://stackoverflow.com/questions/7605217/javas-messagedigest-sha1-algorithm-returns-different-result-than-sha1-function

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!