[英]Proper way to validate password in Java from SQL database?
我正在尝试确定在Java中实现密码验证的最佳方法。 密码以文本形式存储在SQL数据库中。
我是不是该:
如果答案是#1,那么将密码哈希输入Java的正确方法是什么? 我知道密码应该存储为char []而不是String,以避免在内存中留下副本,但是可以使用ResultSet.getString(“ password”)从结果集中检索密码吗? 那会不会创建String常量并带来安全风险(即使是散列的)? 我看到的另一个选项是将密码存储/转换为SQL中的数组,然后使用ResultSet.getArray()检索它,但这似乎有点多余,除非绝对必要。
编辑:
好的,也许我在与PASSWORD相同的帖子中使用了单词TEXT犯了一个错误,但是我指的是数据类型,而不是说我将密码保存为纯文本格式。 实际上,我明确地问过“将密码哈希输入Java的正确方法是什么”。 请坚持我问您想提供帮助的问题。
散列密码。 比您可以比较的哈希值。
从用户那里选择用户名,其中用户名=用户名和密码_哈希=密码_哈希;
byte[] salt = new byte[16];
random.nextBytes(salt);
KeySpec spec = new PBEKeySpec("password".toCharArray(), salt, 2048, 160);
SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
byte[] hash = f.generateSecret(spec).getEncoded();
System.out.println("salt: " + new BigInteger(1, salt).toString(16));
System.out.println("hash: " + new BigInteger(1, hash).toString(16));
这两种方法都不好,因为密码可能是通过网络在应用程序外部以纯文本格式传输的。 但是第二种方法稍好一些,因为某些传输密码有时会出错。
使用某种哈希。 哈希密码,然后将其存储到数据库中。 哈希也输入密码并比较哈希。 散列是不可逆的数据转换。 使用MessageDigest类http://docs.oracle.com/javase/6/docs/api/java/security/MessageDigest.html在Java中创建哈希。 使用数据库知道的一种。
选项3:完全不同。
步骤1: SELECT passwordHASH from users WHERE username=?
(请注意占位符以避免SQL注入攻击-检查有关如何使用占位符的API)
步骤2:从密码哈希中提取盐 。
步骤3:使用Salt从用户收到的纯文本中计算哈希
步骤4:将现有的passwordHash与新计算的passwordHash进行比较。
认真 :阅读盐腌的密码哈希。 这是存储密码的唯一正确方法。 最好的是,它已经存在。 除非您是密码学天才(否则您应该更了解),否则甚至不要尝试重新发明这个轮子。
不要忘记哈希。 当两个用户恰好选择相同的密码时,它可以防止两个用户具有相同的哈希。 另外,它在很大程度上避免了字典攻击,例如彩虹表。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.