【问题标题】:SHA1 in Java and PHP with different resultsJava和PHP中的SHA1具有不同的结果
【发布时间】:2013-11-30 19:44:29
【问题描述】:

我知道有几个这样的问题,但我尝试了我在 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 中,我做了以下事情:

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

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

更新 2

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

的输出 Java

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 编码,但我仍然想知道我可以做些什么来使它工作。

【问题讨论】:

  • 您的哈希值可能采用不同的编码方式。例如。如果使用十六进制编码,你必须确保你在 php 和 java 上都这样做
  • 是的,请确保将字节数组正确转换为十六进制字符串。
  • 您在 Base64 encodeToString 中使用了 toHash 2 次。我怀疑那是你的意图。在 Java 中,您是 Base64 编码“qwerty”,然后计算 sha1,而在 PHP 中,您以相反的方式进行。

标签: java php android sha1


【解决方案1】:

编辑

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

这段代码

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

我猜你打错了

【讨论】:

  • 它打印出正确的结果......这让我更加困惑问题出在哪里:/
  • 你自己试过了吗?这段代码和你的有什么区别?你用的是什么java版本(没关系)
  • 是的,我做了,请参阅我刚刚进行的编辑以获得更详细的解释。我正在使用 Java 1.7.0_45-b18
  • 对不起,我应该更清楚,这只是为了说明 base64 编码字符串的 sha1 在 Java 和 PHP 上是不同的。我实际上做一个或另一个。基本上我的意思是:sha1(Base64.encodeToString("qwerty".getBytes("ASCII"), Base64.DEFAULT)) != sha1(base64_encode("qwerty")) 第一部分是 Java,!= 之后的部分是 PHP。一旦我可以再次编辑我的问题,我会添加这个。
  • 根据您的最新编辑,您说不匹配是在 Base64 编码中,而不是在 sha1 中?我建议您编辑您的问题或关闭此问题并仅使用必要的信息创建一个新问题。可以完全放弃 sha 计算。
【解决方案2】:

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

在我进行此更改后,它开始工作

【讨论】:

    猜你喜欢
    • 2015-09-15
    • 1970-01-01
    • 2021-06-06
    • 2012-10-12
    • 2011-03-13
    • 2011-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多