我有一个实用程序类,其中有一个负责加密用户密码的方法。这是方法:
public static String encryptPassword(String password) {
MessageDigest md = null;
try {
md = getInstance("sha-512");
} catch (NoSuchAlgorithmException ex) {
Logger.getLogger(PasswordUtils.class.getName()).log(Level.SEVERE, null, ex);
throw new IllegalArgumentException();
}
md.update(password.getBytes());
return Base64.getEncoder().encodeToString(md.digest());
}
我正在使用MySQL
来保留我的数据,并希望将密码保留为VARCHAR
。为了了解所需的长度,我做了一些研究,发现this post和this one谈论了所需的长度128.我用几个字符串和String.length()
方法手动测试了方法散列字符串的长度为88.我还看到了一个示例项目并使用'VARCHAR(100)'来存储密码。
此算法的VARCHAR
的最佳大小是多少?提前感谢您的回答。
答案 0 :(得分:1)
sha512哈希的长度是512bit = 64byte / chars。因此,如果您只是将普通哈希存储为MySQL中的二进制字段,则需要64字节。
如果使用base64存储它们,则需要88个字符:base64每个字符只能存储6位信息,而不是普通字符的8位信息。所以你需要512bit / 6bit / char = 85,3bit。 Base64有一些填充规则,它必须始终用零填充数据,直到位数为6的倍数,因此填充到528bit / 6bit = 88bit。这是你需要的固定号码。
除此之外,存储简单哈希的密码永远不是一个好主意。它们可以通过彩虹表攻击轻松逆转。我确信有一些Linux crypt()兼容的java函数,它使用salt和几千轮来防止彩虹表攻击。
答案 1 :(得分:-1)
SHA-512以及所有哈希函数都不加密。
简单地哈希密码不够且不安全,它们会遭受彩虹表攻击。至少需要一个含有随机盐的HMAC,但我们可以而且应该做得更好。
使用诸如Bcrypt,password_hash,PBKDF2等类似使用HMAC的函数并迭代使得该函数需要大约100ms,这是工作因素。
请参阅OWASP(开放式Web应用程序安全项目)Password Storage Cheat Sheet。
请参阅Security StackExchange上的How to securely hash passwords, The Theory。
只有在您希望密码安全时才需要这样做 - 您的用户应该这样做。
来自DRAFT NIST Special Publication 800-63B Digital Authentication Guideline:
“ Verifiers SHALL以一种抵抗离线攻击的形式存储记忆的秘密。秘密应使用批准的哈希函数(如[SP800-132]中所述的PBKDF2)用盐值进行哈希处理。盐值应该是由批准的随机数生成器生成的32位(或更长)随机值,并与散列结果一起存储。应该执行散列函数的至少10,000次迭代。“