Java 使用MySQL验证用户身份的最佳方法(接受其他建议)?
我正在创建一个基于web的登录系统,为此我使用MySQL作为后端,使用JSP和Servlet作为功能,还使用一个名为jasypt 1.8的库来加密密码,以便以后将其存储在MySQL上 我的问题是:以下代码(安全相关、最佳实践等)是否有任何错误: 我不知道将用户从数据库中取出,然后将其与提供的密码进行比较是否正确(即,我认为最好的方法是使用用户名和密码从数据库中取出信息,而不仅仅是前者)。不幸的是,我无法做到这一点,因为我无法生成密钥,因为库中没有能够生成密钥的方法(而且我还无法在文档中找到生成密钥的算法) 我这样做是因为我使用的库有一个内置的随机salt生成器,它将自己存储在加密后创建的字符串中(如果重要的话,使用sha-256…),并且checkPassword()方法是唯一能够生成与数据库中存储的密钥完全相同的密钥的方法(已通过加密过程) 无论如何,如果你有创建登录系统的经验,或者知道很多安全最佳实践,如果你觉得我的解决方案不合适,我希望你能告诉我你对此类问题的经验Java 使用MySQL验证用户身份的最佳方法(接受其他建议)?,java,mysql,jsp,servlets,Java,Mysql,Jsp,Servlets,我正在创建一个基于web的登录系统,为此我使用MySQL作为后端,使用JSP和Servlet作为功能,还使用一个名为jasypt 1.8的库来加密密码,以便以后将其存储在MySQL上 我的问题是:以下代码(安全相关、最佳实践等)是否有任何错误: 我不知道将用户从数据库中取出,然后将其与提供的密码进行比较是否正确(即,我认为最好的方法是使用用户名和密码从数据库中取出信息,而不仅仅是前者)。不幸的是,我无法做到这一点,因为我无法生成密钥,因为库中没有能够生成密钥的方法(而且我还无法在文档中找到生成密
感谢您抽出时间。Jasypt确实让您能够轻松地进行此类密码检查,因此检查密码的代码非常好 我想说的主要一点是,在这种方法中有两种情况
- 获取sql连接
- 在控制台上打印连接消息
- 获取用户
- 检查它是否不为空
- 使用内部StrongPasswordEncryptor检查密码
- 使用日志记录系统
- 将连接的配置分离到其他位置(属性文件…)
- 最终使用一个连接池(这里有一个
- 不要有enpty catch块,抛出异常,或者至少记录它,这样您就知道发生了什么
- 此外,如果您想更改密码,您应该将密码加密机制设置在此方法之外
瞧。希望这个答案能让人明白一点。考虑到用户名在系统中是唯一的,您读取用户信息和比较密码散列的解决方案是可以的,它是广泛使用的解决方案。只要整个处理在服务器端完成,就不涉及安全风险
但是,如果您想在实际应用中使用这样的代码,您不应该每次创建连接,而是考虑使用连接池,例如Apache CuMon DCP,这又简化了开发; 还使用名为jasypt 1.8的库加密密码
你不能加密密码。你应该对密码进行单向散列,然后比较散列。你不能提供任何可以合法解释为让其他人知道用户密码的方法。否则你将失去交易的合法不可抵赖性,这将严重到让你破产。你需要听取法律建议关于这一点,我真的很认真。回答很好,在阅读本文之前,我从来没有想过要使用连接池,立即实施,而且我肯定要使它更加模块化。这只是我为自己做的一个概念证明,所以我可以得到一些关于需要重做什么的反馈,还有一个问题:什么时候假设我需要将连接的配置分离到一个属性文件中,您指的是为此使用一个新类?或者使用某种文本文件,我将从中读取数据?再次感谢您的反馈。除了上面的建议之外,我建议您在查询中只选择密码字段,因为它是e只有一个您使用。这样您就可以避免传输未使用的数据和较低的带宽使用。@user815922是的,一个文本文件。Jasypt有几个例子。很抱歉,我猜我误解了加密的概念,Jasypt的库实际上是对每个密码进行单向散列(大约有5000次SHA-256方法的迭代)之后,它被存储在MySQL数据库中,然后方法checkPassword()(也来自Jasypt的库)检查存储在已经单向散列的密码中的salt,生成密码,并将其与数据库中的密码进行比较,以检查它们是否相等,请告诉我我是否做错了。
protected boolean verifyUser(String user, String pass) throws SQLException, ClassNotFoundException, InstantiationException, IllegalAccessException {
StrongPasswordEncryptor passwordEncryptor = new StrongPasswordEncryptor();
Connection conn = null;
String userName = "****";
String password = "****";
String url = "jdbc:mysql://localhost:3306/DB";
ResultSet rs = null;
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
conn = DriverManager.getConnection(url, userName, password);
System.out.println("Database connection established");
PreparedStatement stmt = null;
stmt = conn.prepareStatement("SELECT * FROM DB.LOGINS WHERE USER = ?");
stmt.setString(1, user);
rs = stmt.executeQuery();
if(!rs.next()){
return false;
}
if(passwordEncryptor.checkPassword(pass, rs.getString("Password"))){
return true;
}
conn.close();
} catch (Exception e) {
}
return false;
}