简体   繁体   English

PHP sha256 hash 不同于 Java 番石榴一

[英]PHP sha256 hash different than Java Guava one

I'm trying to validate sha256 hashes generated via Java Guava Hashing class using PHP, but can't seem to do it.我正在尝试使用 PHP 验证通过 Java Guava Hashing class 生成的 sha256 哈希,但似乎无法做到。 I can't touch Java files, so fix has to be done on PHP side.我无法触摸 Java 文件,因此必须在 PHP 端进行修复。 Both PHP and Java use UTF-8 encoding. PHP 和 Java 都使用 UTF-8 编码。 What am I missing?我错过了什么?

Java: Java:

package org.test.hash;

import com.google.common.hash.Hashing;

public class Main {
    public static void main(String[] args) throws Exception
    {
        String salt = "0123456789012345";
        String password = "password";

        System.out.println(
            Hashing.sha256().hashUnencodedChars(salt + "|" + password).toString()
        );
    }
}

Output: Output:

818112d34d341ace8b9325fce61e676a125f733e25c28c9ed172c1f7d2c3aa6c

PHP: PHP:

$salt = "0123456789012345";
$password = "password";
print_r(hash("sha256", $salt . "|" . $password));

Output: Output:

1f0a70940ae365e930c51e3de4c0a82f853f7663fc17acd36406982666685703

It's a string encoding difference, check the following with Python:这是字符串编码的差异,用 Python 检查以下内容:

>>> from hashlib import sha256
>>> string = "0123456789012345|password"

>>> sha256(string.encode("utf-8")).hexdigest()
'1f0a70940ae365e930c51e3de4c0a82f853f7663fc17acd36406982666685703'

>>> sha256(string.encode("utf-16-le")).hexdigest()
'818112d34d341ace8b9325fce61e676a125f733e25c28c9ed172c1f7d2c3aa6c'

>>> string.encode("utf-8").hex()
'303132333435363738393031323334357c70617373776f7264'

>>> string.encode("utf-16-le").hex()
'30003100320033003400350036003700380039003000310032003300340035007c00700061007300730077006f0072006400'

I figured it out thanks to suggestions from comments.感谢评论中的建议,我想通了。 It seems that bad implementation on Java end (using hashUnencodedChars instead of hashString ) is causing conversion from source encoding (UTF-8 in my case) to UTF-16LE. Java 端(使用hashUnencodedChars而不是hashString )上的错误实现似乎导致从源编码(在我的情况下为 UTF-8)转换为 UTF-16LE。 Here's a way to fix that on PHP side:这是在 PHP 端解决此问题的方法:

$salt = "0123456789012345";
$password = "password";
$salted = mb_convert_encoding($salt . "|" . $password, "UTF-16LE", "UTF-8")
print_r(hash("sha256", $salted));

Output: Output:

818112d34d341ace8b9325fce61e676a125f733e25c28c9ed172c1f7d2c3aa6c

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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