在Java中使用盐与PHP完全相同的哈希?(SHA-256)

Run*_*ion 4 php java sha256

我可以用PHP在PHP中哈希:

$orig_pw = "abcd";
$salt = 5f8f041b75042e56;
$password = hash('sha256', $orig_pw . $salt);
Run Code Online (Sandbox Code Playgroud)

(这不是我实现它的方式,这只是一个例子.盐对每个人都不同)

有了这个,存储的密码是:

bc20a09bc9b3d3e1fecf0ed5742769726c93573d4133dbd91e2d309155fa9929
Run Code Online (Sandbox Code Playgroud)

但是如果我尝试在Java中做同样的事情,我会得到不同的结果.我试过了String password = "abcd";

byte[] salt = hexStringToByteArray("5f8f041b75042e56");

try {
    System.out.println(new String(getHash(password, salt)));
} catch (NoSuchAlgorithmException e1) {
    e1.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)

这两种方法:

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;
    }
Run Code Online (Sandbox Code Playgroud)

结果是:

/¬1¶??ëüFd?[$?¶»_9ËZ»ç¶S‘??—ש
Run Code Online (Sandbox Code Playgroud)

哪个编码为十六进制甚至不接近它:

2fac31b6434c14ebfc46643f5b243fb6bb5f39cb5abb10e7b65391454c97d7a90d0a
Run Code Online (Sandbox Code Playgroud)

有人能帮忙吗?

Rob*_*sen 7

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

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;
}
Run Code Online (Sandbox Code Playgroud)

在对字节进行十六进制后,它返回以下结果:

60359BC8A0B09898335AA5A037B1E1B9CE3A1FE0D4CEF13514901FB32F3BCEB0
Run Code Online (Sandbox Code Playgroud)

在PHP中:

<?
echo hash('sha256', "abcd"."5f8f041b75042e56");
?>
Run Code Online (Sandbox Code Playgroud)

返回完全相同.