为了给你一些背景知识,我和我的团队正在创建一个程序,用于在数据库中存储用户名和密码。我们正在使用Java并通过Java代码与数据库交互。
我们使用Jasypt加密用户名和密码。我在Jasypt中使用BasicPasswordEncryptor来加密这两者。用户名加密很好,并存储在数据库中。但是,当检查登录并且所述BasicPasswordEncryptor尝试根据加密密码检查明文用户名时,它总是返回false。我已经做了一系列检查,以便关注问题发生的地方。据我所知,这是Jasypt的一个问题。有谁知道问题是什么,可能的解决方案,还是更优化的方法?谢谢。我会发布代码。
这是加密发生的地方。
public void register(String userName, String passWord){
String encryptedUsername = e.encryptPassword(userName);
String encryptedPassword = e.encryptPassword(passWord);
System.out.println("Registered eU: " + encryptedUsername);
try {
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/PandaBox", "root", "");
statement = con.prepareStatement("insert into Users (username, password, logged) values (?,?,?)");
statement.setString(1, encryptedUsername);
statement.setString(2, encryptedPassword);
statement.setInt(3, 0);
boolean x = statement.execute();
System.out.println("IT REGISTERED");
} catch (SQLException o) {
o.printStackTrace();
}
}
其中“e”是BasicPasswordEncryptor对象。这是登录检查。
public boolean checkLogin(String inputedUsername, String inputedPassword) {
try {
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/PandaBox", "root", "");
statement = con.prepareStatement("select * from Users");
rs = statement.executeQuery();
System.out.println(inputedUsername + " / " + inputedPassword);
while(rs.next()){
String usernameInDatabase = rs.getString("username");
System.out.println(usernameInDatabase);
if (e.checkPassword(inputedUsername, usernameInDatabase)) {
System.out.println("Username correct.");
statement = con.prepareStatement("select password from Users where username = ?");
statement.setString(1, usernameInDatabase);
rs = statement.executeQuery();
String passwordInDatabase = rs.toString();
if(passwordIsCorrect(inputedPassword, passwordInDatabase)){
return true;
}
}
}
return false;
} catch (SQLException o) {
// TODO Auto-generated catch block
o.printStackTrace();
return false;
}
}
答案 0 :(得分:1)
我是jasypt的作者。
从您的消息中,我不清楚您在匹配用户名或密码时是否正在观察此问题 - 您说'尝试使用加密密码检查明文用户名',这没有任何意义 - - 。然而,像您这样的问题最常见的原因之一是您的数据库列不够大,无法存储您的哈希用户名和/或密码。
散列结果的大小取决于所使用的算法和salt配置,但对于使用MD5和8字节的salt大小的BasicPasswordEncryptor,您应该期望散列为16字节(散列)加上8个字节(盐),加上8个额外字节,因为文本Base64编码。总共32个字节。
还要认为很多DBMS在字符中测量varchar字段而不是字节,因此您应该根据表中使用的字符编码进行适当的转换。
我总是建议首先检查列大小,因为如果您尝试存储对于列来说太长的varchar,许多DBMS不会引发错误 - 它们只是截断它。我不知道MySQL的行为,但Oracle确实如此。当你试图解密它时...它不匹配。
因此,检查色谱柱尺寸可能是一个很好的起点。请记住jasypt在http://forum.jasypt.org
有一个用户论坛哦,顺便说一下 - 请原谅我,如果这只是特定的演示代码,但为了以下情况:你应该确保在重复使用之前关闭'finally'块中的所有Statement和ResultSet对象。所以你应该在内部迭代块中使用不同的'statement'和'rs'变量,并且每次都关闭它们。
问候。
答案 1 :(得分:-1)
优化1:使用WHERE子句。