我现在试图通过尝试完成下一个目标而奋斗了一段时间: 我有一个"重置密码"应该向服务器发送新密码的页面。我想用盐哈希,所以我最终可以将它保存在DB中。在服务器端,我有下一个创建密码哈希的方法:
public static String makeHash(String password, String salt) {
try {
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(password.getBytes("UTF-8"));
byte byteData[] = md.digest(makeHash(salt.toLowerCase()));
return Base64.getEncoder().encodeToString(byteData);
} catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
log.error("Unable to make hash for pass. No hashing.", e);
}
return password;
}
private static byte[] makeHash(String val) throws NoSuchAlgorithmException, UnsupportedEncodingException {
return MessageDigest.getInstance("SHA-256").digest(val.getBytes("UTF-8"));
}
我尝试了几个Javascript库 - crypto,crypto-js,SJCL,但无法创建与Java方法生成相同的密码。例如,上次工作尝试是:
var crypto = require('crypto');
crypto.pbkdf2('123', 'test@gmail.com', 1000, 60, 'sha256', function(err, key) {
if (err)
throw err;
console.log(key.toString('Base64')); // 'c5e478d...1469e50'
});
它生成了这个哈希 - Qr2lzotlRWj7BeJeFooMRj64auMPTb3PRhwLmfNcl4DCVAlFFibgOqZiyExZNO5i/icAUYoMjy73jSTd
,而Java给了我 - /pyQf3JCj5XoczfsYJ4LUb+y0DONGMl/AFzLiBTo8LA=
。
我无法改变后端,因为它已经运行了一段时间,所以我希望也许有人可以帮我解决这个问题。
答案 0 :(得分:3)
您必须在两侧使用相同的算法。在Java中,您只使用SHA-256,在节点中,您使用的是带有SHA-256的PBKDF2。
Node.js的加密模块提供createHash(algorithm)
功能。您可以在哪里直接指定SHA-256。 PBKDF2是一种仅在引擎盖下使用不同散列函数的算法。
如果你想要哈希密码,那么使用PBKDF2进行大量迭代(> 86,000)以及随密码哈希存储的随机盐会更安全。
Java在其标准库中支持PBKDF2。
如果你真的想直接使用SHA-256并且我强烈反对它,你可以使用以下代码:
var crypto = require('crypto');
var key = "123";
var salt = "test@gmail.com";
key = crypto.createHash('sha256')
.update(key, "utf8")
.update(makeHash(salt))
.digest("base64");
console.log(key);
function makeHash(val) {
return crypto.createHash('sha256').update(val, "utf8").digest();
}
输出:
/pyQf3JCj5XoczfsYJ4LUb+y0DONGMl/AFzLiBTo8LA=
请注意Hash.digest()
采用可选的输出编码,而不是其他数据。