java 哈希值相同,像symfony2一样创建相同的哈希值(java-SHA-512)

我在这里有一个旧的基于Symfony2的应用程序,我正在使用Java中的Dropwizard开发替代品.

我将旧DB中的所有用户记录迁移到我的新Datamodel中.

我还为密码添加了新字段,并导入了旧密码和盐字段.

现在我想做出众所周知的程序.让用户登录,尝试新密码字段.如果失败,请尝试迁移的,如果它们有效,则使用新算法对明文密码进行编码,并将新散列存储在新的密码字段中.这样用户就可以将旧程序中的密码哈希移植到新程序.

听起来简单而且规范,它像往常一样工作,但这个Symfony和PHP让我发疯.

我坚持的地方是使用java创建与symfony相同的哈希.

旧应用程序使用带有“sha512”,base64编码和5000次迭代的MessageDigestPasswordEncoder,所有默认值;)

重要的方法是:

MessageDigestPasswordEncoder:

public function encodePassword($raw, $salt) {

if ($this->isPasswordTooLong($raw)) {

throw new BadCredentialsException('Invalid password.');

}

if (!in_array($this->algorithm, hash_algos(), true)) {

throw new \LogicException(sprintf('The algorithm "%s" is not supported.', $this->algorithm));

}

$salted = $this->mergePasswordAndSalt($raw, $salt);

$digest = hash($this->algorithm, $salted, true);

// "stretch" hash

for ($i = 1; $i < $this->iterations; ++$i) {

$digest = hash($this->algorithm, $digest.$salted, true);

}

return $this->encodeHashAsBase64 ? base64_encode($digest) : bin2hex($digest);

}

和BasePasswordEncoder:

protected function mergePasswordAndSalt($password, $salt) {

if (empty($salt)) {

return $password;

}

if (false !== strrpos($salt, '{') || false !== strrpos($salt, '}')) {

throw new \InvalidArgumentException('Cannot use { or } in salt.');

}

return $password.'{'.$salt.'}';

}

这似乎是直截了当但我坚持下去.

当我读到它时,它确实:

>将salt和明文密码合并为:“password {salt}”

>使用SHA-512散列此字符串,并将二进制字符串返回到摘要变量

>迭代5k次并使用与合并的明文密码连接的摘要重新进入摘要

>将摘要编码为base64

所以这是我在Java中的尝试:

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import org.slf4j.Logger;

import java.io.UnsupportedEncodingException;

import java.security.MessageDigest;

import java.security.NoSuchAlgorithmException;

import java.util.Base64;

public void legacyEncryption(String salt, String clearPassword) throws UnsupportedEncodingException, NoSuchAlgorithmException {

// Get digester instance for algorithm "SHA-512" using BounceCastle

MessageDigest digester = MessageDigest.getInstance("SHA-512", new BouncyCastleProvider());

// Create salted password string

String mergedPasswordAndSalt = clearPassword + "{" + salt + "}";

// First time hash the input string by using UTF-8 encoded bytes.

byte[] hash = digester.digest(mergedPasswordAndSalt.getBytes("UTF-8"));

// Loop 5k times

for (int i = 0; i < 5000; i++) {

// Concatenate the hash bytes with the clearPassword bytes and rehash

hash = digester.digest(ArrayUtils.addAll(hash, mergedPasswordAndSalt.getBytes("UTF-8")));

}

// Log the resulting hash as base64 String

logger.info("Legace password digest: salt=" + salt + " hash=" + Base64.getEncoder().encodeToString(hash));

}

有人看到了这个问题吗?我认为不同之处在于:

PHP:binary.binary

JAVA:addAll(byte [],byte [])

提前致谢

解决方法:

php端的实现是通过第一轮散列然后循环4999次正确地进行5k次迭代.

$digest = hash($this->algorithm, $salted, true);

for ($i = 1; $i < $this->iterations; ++$i) {

$digest = hash($this->algorithm, $digest.$salted, true);

}

在java实现中,for循环从0开始,这导致5k 1迭代.

通过在java中以1开始for循环,结果密码哈希值等于.

byte[] hash = digester.digest(mergedPasswordAndSalt.getBytes("UTF-8"));

for (int i = 0; i < 5000; i++) {

hash = digester.digest(ArrayUtils.addAll(hash, mergedPasswordAndSalt.getBytes("UTF-8")));

}

标签:php,java,hash,symfony,sha

来源: https://codeday.me/bug/20190623/1267857.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值