Java和PHP中的SHA1具有不同的结果

时间:2013-11-17 18:33:17

标签: java php android sha1

我知道有几个这样的问题,但我尝试了在stackoverflow上找到的每一个解决方案,但我仍然没有得到预期的结果。

我正在尝试在Java和PHP中将字符串转换为sha1,但我得到了不同的结果。该字符串是随机生成的。我检查了两端的字符串,它们是相同的(甚至尝试在线比较工具)。

这是我在另一个应用程序中使用的相同代码,它在那里工作,但不是在这种情况下。

我尝试使用sha1散列的一个字符串是:UgJaDVYEClRUD1cAAVUBVwRTB1MDAA9SBgcDBwNXAwNZBQdUAAACBA==

Java结果:72c9bbe7eed0efe5e82ea9568136d8f52347259e

PHP结果:f720d73d18a7bb9cf36808af17ce40621ebfb405

Java代码

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代码

sha1("UgJaDVYEClRUD1cAAVUBVwRTB1MDAA9SBgcDBwNXAwNZBQdUAAACBA==");

任何帮助将不胜感激

更新

在Java& PHP我正在做以下事情:

爪哇

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

我想Base64编码对PHP和Java上不同的字符串做了些什么,有什么想法?

更新2

我应该更清楚,对不起,我的意思是:

输出 的爪哇

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

输出不同 的 PHP

sha1(base64_encode("qwerty"));

更新3

虽然两个base64编码的字符串都相等cXdlcnR5

基本上:

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

我已经在我散列的字符串上删除了base64编码,但我仍然想知道我可以做些什么才能使它工作。

2 个答案:

答案 0 :(得分:4)

修改

您在toHash方法中使用了encodeToString变量两次,这使您的第二行代码变得多余。

此代码

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

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

相当于此代码

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

所以基本上在java中你是

  • 获取“qwerty”的Base64
  • 获得该结果的sha1

使用PHP时你是

  • 获取“qwerty”的sha1
  • 获得该结果的Base64

我认为你错误输入了

答案 1 :(得分:0)

3年后,我遇到了同样的问题,但这次我发现了问题。对于任何偶然发现这个问题的人来说,这是解决方案:

我正在使用:

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

问题是Base64.DEFAULT,Base64的默认行为包装了字符串(将\n添加到字符串中)。 为了获得与PHP方法相同的结果,您应该使用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"))

我做了这个改变之后就开始工作了