我在这里有一个旧的基于Symfony2的应用程序,我正在用Java开发Dropwizard替代它。我将所有用户记录从旧数据库迁移到新的数据模型中。我还为密码添加了新字段,并导入了旧密码和盐字段。
现在我想做一个众所周知的程序。让用户登录,对新密码字段进行尝试。如果失败,尝试迁移的密码,如果它们工作,用新算法编码明文密码,并将新哈希存储在新密码字段中。因此,用户将密码哈希从旧过程移植到新过程。
听起来简单而正常,一切照旧,但这个Symfony和PHP让我抓狂。
我坚持的地方是用java创建相同的哈希,就像Symfony一样。旧的应用程序使用MessageDigestPasswordEncoder与sha512,Base64编码和5000次迭代,所有默认值;)
重要的方法是:
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.'}';
}
这似乎是直截了当的,但我坚持下去了。当我读到这篇文章时,它确实:
下面是我在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开始,导致5k1次迭代。
通过在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")));
}
问题内容: 我一直在研究一些有关Java字符串加密技术的信息,但不幸的是,我还没有找到如何在Java中使用SHA-512对String进行哈希处理的很好的教程。我读了一些有关MD5和Base64的博客,但是它们并不像我想要的那样安全(实际上,Base64不是一种加密技术),所以我更喜欢SHA-512。 问题答案: 您可以将其用于SHA-512
我一直在使用PHP为Dovecot创建一个可用的盐渍SHA-512哈希。当创建一个非salt十六进制格式的哈希时,一切都很好。向哈希中添加一个盐,我无法再使用“doveadm pw”验证哈希。 这是我的代码: var\u dumps()的输出如下: 现在,当我尝试根据doveadm验证哈希时,只有第一个哈希(十六进制格式的非salt)有效。第二个错误是关于字符串长度的错误(输入长度无效(128而不
作为练习,我用C编写了自己的SHA-512哈希函数实现。我知道它是有效的,因为我从abc 在Base64中。就像在测试现场一样。 我有两个问题: > 如何加密我的密码?如果我有: 我应该创建字符串以输入盐通过="ssssssssmy密钥密码"吗?或者可能以相反的方式?我试图在谷歌上到处寻找答案——我找不到真正合适的东西。 在base64中,我应该使用什么编码来获得像/etc/shadow文件中那样
我想找到一个解决方案或方法,使我能够添加盐和控制迭代次数。本机Rfc2898DeriveBytes基于HMACSHA1。理想情况下,使用SHA-256或SHA-512将使系统经得起未来的考验。 这是迄今为止我发现的最好的例子:http://jmedved.com/2012/04/pbkdf2-with-sha-256-and-others/但是当我用SHA-256运行它时,它实际上比用SHA-51
我对密码学是个新手,但是学习。我从网上的研究中收集了许多不同的建议,并制作了自己的类,用于处理哈希、salt、键拉伸以及关联数据的比较/转换。 在研究了内置的。NET密码学库,我发现我拥有的仍然只有SHA-1。但我得出的结论是,这并不坏,因为我使用了哈希过程的多次迭代。对吗? 但如果我想从更健壮的SHA-512开始,我如何在下面的代码中实现它呢?提前谢谢。 注意:我已经参考了很多来自https:/
想要改进此问题?更新问题,以便它仅通过编辑这篇文章来关注一个问题。 我们需要读取文件内容并将其转换为SHA256,然后将其转换为Base64。 任何指针或示例代码都足够了,因为我是这个加密机制的新手。 提前谢谢。