Java 和 PHP 之间盐不匹配的 SHA-512

SHA-512 with salt not matching between Java and PHP

我的应用程序在 Java 中使用加盐哈希。首先生成随机盐。然后将此盐作为输入密码的 SHA-512 前缀,组合字符串为 SHA-512 again.It 实现如下:-

String password = testpwd.getText().toString();
SecureRandom rand = new SecureRandom();
byte[] randbytes = new byte[16];
rand.nextBytes(randbytes);
String encodedSalt = Base64.encodeToString(randbytes, Base64.DEFAULT);

MessageDigest digest = MessageDigest.getInstance("SHA-512");
digest.reset();
digest.update(password.getBytes("utf-8"));
byte[] pwdhash = digest.digest();
String encodedPwd = Base64.encodeToString(pwdhash, Base64.DEFAULT);

String saltedPassword = encodedSalt+encodedPwd ;

digest.reset();
digest.update(saltedPassword.getBytes("utf-8"));
byte[] pwdhash1 = digest.digest();
String encodedPwdSalt = Base64.encodeToString(pwdhash1, Base64.DEFAULT);

然后将字符串encodedSalt 和encodedPwdSalt 发送到Web 服务器进行身份验证。 PHP加密如下:

$postpassword = $_POST['password'];
$postsalt = $_POST['salt'];
$salt = base64_decode($postsalt);
$password = base64_decode('postpassword');

密码 "Ditglt@785" 的 SHA-512 哈希存储在数据库中。检索和处理如下:-

$getsaltpwd = $salt.$dbpassword ;
$dbsaltpwd = hash('sha512', $getsaltpwd);
if($dbpassword == $postpassword) {}

条件总是失败,身份验证也是如此。我该怎么办?

检查填充是否匹配。我遇到了与加密相同的问题,其中 PHP 中的填充与 JAVA 中的填充不同。幸运的是,我能够将 JAVA 中的填充设置为 PHP 使用的填充。但我必须查看 PHP 源代码才能弄清楚如何。据我所知,当时无法更改 PHP 中的填充。

这是我当时发的问题:decrypting php encrypted data on android

[...] you need to set Base64.decode with the parameter Base64.NO_WRAPas PHP will just put out the base64 delimited by [=10=].

PHP 版本哈希 raw 字节,而 Java 版本哈希 base64-encoded 字符串。

这是一个 Java 版本,与您的 PHP 代码的功能相匹配:

digest.reset();
digest.update(randbytes);
digest.update(pwdhash);
byte[] pwdhash1 = digest.digest();
String encodedPwdSalt = Base64.encodeToString(pwdhash1, Base64.DEFAULT);

话虽如此,将 saltsalted 密码 存储在数据库中并在至少一些key derivation function(多次迭代哈希函数)以抵消存储哈希的任何潜在暴力破解。

由于您的 Java 代码正确地遵循了您在规范中描述的内容,问题出在 PHP 方面。

按原样使用您的 Java 代码,在使用随机盐对字符串 "password" 进行编码时,它会生成以下值:

encodedSalt: ww0g+f77ygKD7Iww1GTYtg==
encodedPwd: sQnzu7wkTrgkQZF+0G1hi5AI3Qmzvv0bXgc5THBqi7mAsdd4Xll27ASbRt9fEyavWi6m0QP9B8lThf+rDKy8hg==
encodedPwdSalt: YAGG7GcpUxIZzBnHuaezPf5BWFhFalBPgvue/0wFoRLu+JsKslG8wPCv6dPubIBk1aFIJ8spK8S17347aDBAYA==

在PHP中,您需要做的是:

$postpassword = 'YAGG7GcpUxIZzBnHuaezPf5BWFhFalBPgvue/0wFoRLu+JsKslG8wPCv6dPubIBk1aFIJ8spK8S17347aDBAYA==';
$postsalt = 'ww0g+f77ygKD7Iww1GTYtg==';
$dbpassword = 'sQnzu7wkTrgkQZF+0G1hi5AI3Qmzvv0bXgc5THBqi7mAsdd4Xll27ASbRt9fEyavWi6m0QP9B8lThf+rDKy8hg==';

if($postpassword == base64_encode(hash('sha512', $postsalt.$dbpassword, true))) {
    echo 'OK';
}