Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java中的哈希与PHP中的salt完全相同?(SHA-256)_Java_Php_Sha256 - Fatal编程技术网

java中的哈希与PHP中的salt完全相同?(SHA-256)

java中的哈希与PHP中的salt完全相同?(SHA-256),java,php,sha256,Java,Php,Sha256,我可以简单地用盐在PHP中散列: $orig_pw = "abcd"; $salt = 5f8f041b75042e56; $password = hash('sha256', $orig_pw . $salt); (这不是我实现它的方式,这只是一个例子。盐对每个人都是不同的) 这样,存储的密码是: bc20a09bc9b3d3e1fecf0ed5742769726c93573d4133dbd91e2d309155fa9929 但是如果我在Java中尝试同样的方法,我会得到不同的结果。我尝试

我可以简单地用盐在PHP中散列:

$orig_pw = "abcd";
$salt = 5f8f041b75042e56;
$password = hash('sha256', $orig_pw . $salt);
(这不是我实现它的方式,这只是一个例子。盐对每个人都是不同的)

这样,存储的密码是:

bc20a09bc9b3d3e1fecf0ed5742769726c93573d4133dbd91e2d309155fa9929
但是如果我在Java中尝试同样的方法,我会得到不同的结果。我尝试了
String password=“abcd”

以及两种方法:

public byte[] getHash(String password, byte[] salt) throws NoSuchAlgorithmException {
        MessageDigest digest = MessageDigest.getInstance("SHA-256");
        digest.reset();
        digest.update(salt);
        try {
            return digest.digest(password.getBytes("UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return null;
    }


public byte[] hexStringToByteArray(String s) {
        int len = s.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                                 + Character.digit(s.charAt(i+1), 16));
        }
        return data;
    }
编码为十六进制的代码甚至不接近它:

2fac31b6434c14ebfc46643f5b243fb6bb5f39cb5abb10e7b65391454c97d7a90d0a
有人能帮忙吗?

我想

digest.update(salt);
digest.digest(password.getBytes("UTF-8"));
相当于:

hash('sha256', $salt . $orig_pw);

所以散列和盐被交换了。您能确认这一点吗?

除了交换的顺序之外,在PHP中,您将salt值视为要附加到密码的文本字符串,而在Java中,您首先对salt进行十六进制转换,然后使用生成的字节更新
消息摘要
。这显然会产生不同的结果。只看盐:

PHP:Salt->To bytes(literal)->SHA-256
Java:Salt->To bytes(unhex)->SHA-256

我刚刚试过你的Java代码,它非常好。我还尝试在PHP中散列与Java中相同的值,它给出了相同的结果

与PHP代码相当的Java代码是:

String password = "abcd";
String salt = "5f8f041b75042e56";

try {
    MessageDigest digest = MessageDigest.getInstance("SHA-256");

    return digest.digest((password + salt).getBytes("UTF-8"));
} catch (UnsupportedEncodingException | NoSuchAlgorithmException e) {
    return null;
}
对字节进行十六进制运算后,返回以下结果:

60359BC8A0B09898335AA5A037B1E1B9CE3A1FE0D4CEF13514901FB32F3BCEB0
在PHP中:

<?
echo hash('sha256', "abcd"."5f8f041b75042e56");
?>


返回的值完全相同。

是的,我认为它们是交换的。(如果可能的话,保持这种方式)你不能只是交换它们,输入在PHP和Java中必须是相同的。我的意思是保持在PHP中交换,也在Java中交换。我不理解每个单词(不是英语)。那么我应该在爪哇换盐吗?(比如:byte[]salt=“5f8f041b75042e56”。getBytes();)另外,我如何在java中交换它们?我不知道您实际的PHP代码是什么样子(您发布的代码不会运行,因为没有十六进制字符串)。然而,您似乎正在散列
“abcd”;“5f8f041b75042e56”
。要在Java中实现类似的功能,您必须先执行
(“password”+“salt”).getBytes(“UTF-8”)
,然后对其进行消化。是的,很抱歉,代码不是这样实现的。实际代码得到一个随机数:$salt=dechex(mt_rand(02147483647))。德克塞克斯(兰特(02147483647));
60359BC8A0B09898335AA5A037B1E1B9CE3A1FE0D4CEF13514901FB32F3BCEB0
<?
echo hash('sha256', "abcd"."5f8f041b75042e56");
?>