简体   繁体   中英

SHA1 in Java and PHP with different results

I know there are several questions like this around, but I tried every single solution I found on stackoverflow and I still haven't got the expected result.

I'm trying to convert a string to sha1 in Java and PHP, but I'm getting different results. The string is generated randomly. I checked the string on both ends and they are the same (even trying a online comparison tool).

This is the same code I use in another app and it's working there, but not in this case.

One string I tried to hash with sha1 is: UgJaDVYEClRUD1cAAVUBVwRTB1MDAA9SBgcDBwNXAwNZBQdUAAACBA==

Java result: 72c9bbe7eed0efe5e82ea9568136d8f52347259e

PHP result: f720d73d18a7bb9cf36808af17ce40621ebfb405

Java Code

public static String sha1(String toHash)
{
    String hash = null;
    try
    {
        MessageDigest digest = MessageDigest.getInstance("SHA-1");
        byte[] bytes = toHash.getBytes("ASCII"); //I tried UTF-8, ISO-8859-1...
        digest.update(bytes, 0, bytes.length);
        bytes = digest.digest();
        StringBuilder sb = new StringBuilder();
        for(byte b : bytes)
        {
            sb.append(String.format("%02X", b));
        }
        hash = sb.toString();
    }
    catch(NoSuchAlgorithmException e)
    {
        e.printStackTrace();
    }
    catch(UnsupportedEncodingException e)
    {
        e.printStackTrace();
    }
    return hash.toLowerCase(Locale.ENGLISH);
}

PHP code

sha1("UgJaDVYEClRUD1cAAVUBVwRTB1MDAA9SBgcDBwNXAwNZBQdUAAACBA==");

Any help would be appreciated

Update

In Java & PHP I was doing the following:

Java

String toHash = "qwerty";
String hash = sha1(toHash); //Prints: b1b3773a05c0ed0176787a4f1574ff0075f7521e

toHash = Base64.encodeToString(toHash.getBytes("ASCII"), Base64.DEFAULT);
hash = sha1(toHash); //Prints: 88bfb2d77c3b42823bab820c1737f03c97d87c1b

PHP

$toHash = "qwerty";
sha1($toHash); //Prints: b1b3773a05c0ed0176787a4f1574ff0075f7521e

sha1(base64_encode($toHash)); //Prints: 278aa0e8dde2af58a4eed613467da219a35c5278

I guess that the Base64 encoding is doing something to the string that is different on PHP and Java, any thoughts on why?

UPDATE 2

I should have been more clearer, sorry for that, what I mean is:

The output of Java

sha1(Base64.encodeToString("qwerty".getBytes("ASCII"), Base64.DEFAULT));

is different that the output of PHP

sha1(base64_encode("qwerty"));

UPDATE 3

although both base64 encoded string are equal cXdlcnR5 .

Basically:

- sha1("qwerty") == sha1("qwerty")
- Base64.encodeToString("qwerty".getBytes(), Base64.DEFAULT) == base64_encode("qwerty")
- sha1(Base64.encodeToString("qwerty".getBytes(), Base64.DEFAULT)) != sha1(base64_encode("qwerty"))

I already dropped the base64 encoding on the strings that I hash, but I still would like to know what I could have done to make it work.

Edit

you are using the toHash variable twice in the encodeToString method making your second line of code redundant.

this code

String toHash = "qwerty";
String hash = sha1(toHash); //Prints: b1b3773a05c0ed0176787a4f1574ff0075f7521e

toHash = Base64.encodeToString(toHash.getBytes("ASCII"), Base64.DEFAULT);
hash = sha1(toHash); //Prints: 88bfb2d77c3b42823bab820c1737f03c97d87c1b

is equivalent to this code

String toHash = "qwerty";
toHash = Base64.encodeToString(toHash.getBytes("ASCII"), Base64.DEFAULT);
hash = sha1(toHash); //Prints: 88bfb2d77c3b42823bab820c1737f03c97d87c1b

So essentially in java you are

  • getting Base64 for "qwerty"
  • getting the sha1 on that result

While using PHP your are

  • getting the sha1 for "qwerty"
  • getting the Base64 on that result

I assume you've mistyped

Over 3 years later I ran into the same issue, but this time I figured out the problem. Here is the solution to anyone that stumbles upon this question:

I was using:

sha1("qwerty") == sha1("qwerty")
Base64.encodeToString("qwerty".getBytes(), Base64.DEFAULT) == base64_encode("qwerty")
sha1(Base64.encodeToString("qwerty".getBytes(), Base64.DEFAULT)) != sha1(base64_encode("qwerty"))

The problem with this is the Base64.DEFAULT , the default behavior of Base64 wraps the string (adds \\n to string). In order to get the same result as the PHP method you should use Base64.NO_WRAP :

sha1("qwerty") == sha1("qwerty")
Base64.encodeToString("qwerty".getBytes(), Base64.NO_WRAP) == base64_encode("qwerty")
sha1(Base64.encodeToString("qwerty".getBytes(), Base64.NO_WRAP)) == sha1(base64_encode("qwerty"))

After I made this change it started to work

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM