我正在尝试确定在Java中实现密码验证的最佳方法。密码作为文本存储在SQL数据库中。
我应该:
如果答案是#1,那么将密码哈希变为Java的正确方法是什么?我知道密码应该存储为char []而不是String,以避免在内存中留下副本,但是可以使用ResultSet.getString(“password”)从结果集中检索它吗?不会创建一个String常量并且存在安全风险(即使是散列)?我看到的另一个选项是将密码存储/转换为SQL中的数组,然后使用ResultSet.getArray()来检索它,但除非绝对必要,否则这似乎有点过分。
修改
好吧,也许我在与PASSWORD相同的帖子中使用TEXT这个词时犯了一个错误,但我指的是数据类型,而不是说我用纯文本保存密码。事实上,我清楚地问过“将密码哈希转换为Java的正确方法是什么”。如果你想提供帮助,请坚持我问的问题。
答案 0 :(得分:0)
哈希密码。比你可以比较哈希。
SELECT username FROM user WHERE username = username and password_hash = password_hash;
How can I hash a password in 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));
答案 1 :(得分:0)
您的方法都很糟糕,因为密码在应用程序之外以纯文本传输,可能是通过网络传输。但第二种方法略胜一筹,因为有些传输密码有时会出错。
使用某种散列。哈希密码然后将其存储到数据库中。哈希也输入密码并比较哈希值。散列是不可逆转的数据转换。使用MessageDigest类http://docs.oracle.com/javase/6/docs/api/java/security/MessageDigest.html在Java中创建哈希。使用你的数据库知道的一个。
答案 2 :(得分:0)
选项3:完全不同。
第1步:
SELECT passwordHASH from users WHERE username=?
(注意占位符以避免SQL注入攻击 - 检查您的API如何使用占位符)
第2步:从密码哈希中提取 salt 。
步骤3:使用salt根据从用户
收到的纯文本计算哈希值步骤4:将现有的passwordHash与新计算的passwordHash进行比较。
认真:阅读盐渍密码哈希值。这是唯一正确的密码存储方式。最好的是,它已经存在。不要试图重新发明这个轮子,除非你是一个加密天才(然后你应该知道更好)。
不要把哈希留下来。当两个用户碰巧选择相同的密码时,它会阻止两个用户使用相同的哈希值。此外,它在很大程度上避免了字典攻击,例如彩虹表。