我可以简单地在PHP中使用salt进行哈希:
$orig_pw = "abcd";
$salt = 5f8f041b75042e56;
$password = hash('sha256', $orig_pw . $salt);
(这不是我实现它的方式,这只是一个例子。盐对每个人都不同)
这样,存储的密码为:
bc20a09bc9b3d3e1fecf0ed5742769726c93573d4133dbd91e2d309155fa9929
但是如果我尝试在Java中做同样的事情,我会得到不同的结果。我试过了String password = "abcd";
byte[] salt = hexStringToByteArray("5f8f041b75042e56");
try {
System.out.println(new String(getHash(password, salt)));
} catch (NoSuchAlgorithmException e1) {
e1.printStackTrace();
}
这两种方法:
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;
}
结果是:
/¬1¶ĆĽëüFd?[$?¶»_9ËZ»ç¶S‘Ęŗש
哪个编码为十六进制甚至不接近它:
2fac31b6434c14ebfc46643f5b243fb6bb5f39cb5abb10e7b65391454c97d7a90d0a
任何人都可以帮忙吗?
答案 0 :(得分:7)
除了交换订单之外,在PHP中看起来像是将salt值视为要附加到密码的文字字符串,而在Java中,您首先对salt进行十六进制转换然后再使用结果字节更新MessageDigest
。这显然会产生不同的结果。只看盐:
PHP: Salt - &gt; to bytes(literal) - &gt; SHA-256
Java: Salt - &gt;到字节(unhex) - &gt; 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");
?>
返回完全相同。
答案 1 :(得分:2)
我认为
digest.update(salt);
digest.digest(password.getBytes("UTF-8"));
相当于:
hash('sha256', $salt . $orig_pw);
因此哈希和盐被交换。你能证实一下吗?