java base64 salt_带有盐的SHA-512在Java和PHP之间不匹配

我的应用程序在Java中使用了盐腌哈希。 首先,生成随机盐。 然后,该盐前缀为输入密码的SHA-512,组合的字符串再次为SHA-512,其实现方式如下:

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);

然后,将字符串encodeSalt和encodePwdSalt发送到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) {}

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

与$postpassword进行比较时,是否应该使用$dbsaltpwd而不是$dbpassword?

base64_decode(postpassword);在您的第一个PHP块中做什么? (为什么要解码常量?)

您不应该在PHP中使用base64解码盐,因为您在Java中哈希了以base64编码的盐。

@John您应该更具体地了解所需的编码/ concat /哈希步骤的过程。 Java和PHP之间显然不匹配,只能猜测哪个过程是预期的。

@RobbyCornelissen您对"使用$ dbsaltpwd而不是$ dbpassword"是正确的。但这是在此处发布问题时的错字。正如您提到的那样,在代码中。

默认情况下,PHP hash()返回的hexits与base64编码的字符串相比。很抱歉,但是您的实现感觉有点像冰雹玛丽的尝试。检查整个过程中的每个步骤,您应该可以弄清楚。

@RobbyCornelissen但是我在比较之前已经使用base64解码了密码。 $ password = base64_decode(postpassword);

但是,您将其与$postpassword而不是与$password进行比较。而且,即使您与$password进行比较,您仍将十六进制与二进制数据进行比较。

好,谢谢。那我应该如何比较十六进制和二进制数据呢?

PHP版本对原始字节进行哈希处理,而Java版本对base64编码的字符串进行哈希处理。

这是与您的PHP代码相匹配的Java版本:

digest.reset();

digest.update(randbytes);

digest.update(pwdhash);

byte[] pwdhash1 = digest.digest();

String encodedPwdSalt=Base64.encodeToString(pwdhash1, Base64.DEFAULT);

话虽如此,将盐和盐分的密码存储在数据库中,并至少使用一些密钥派生函数(多次迭代哈希函数)以抵消所存储的任何潜在的暴力行为,这将更加安全。哈希。

哦! 我使用了String saltedPassword = encodeSalt + encodedPwd行; 为达到这个

Java版本正在对saltedPassword进行哈希处理,即encode(salt) + encode(hash(password)),大致来说(不是Java语法)。 也许$salt不应该通过base64_decode传递,因为他们似乎想散列编码的盐。

saltedPassword = encodeSalt + encodedPwd; 是不正确的。

由于您的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';

}

谢谢。 我正在尝试

您已经说了我的Java代码,但是根据rustyx的说法,saltedPassword = encodeSalt + encodedPwd部分不正确。

没有什么不对的。 您选择串联两个base64编码的字符串并对其进行哈希处理,而他选择串联两个字节数组并对其进行哈希处理。 结果显然会有所不同,但是一个并不比另一个更正确。

非常感谢@Robby。 我正在将您的答案标记为已接受

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

这是我当时发布的问题:在android上解密php加密数据

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

SHA-512? 填充?

@RobbyCornelissen我从那以后再次看了我的问题,而Base64的问题是定界字符。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值