使用MySQL验证用户的最佳方式(打开其他建议)?

时间:2011-08-24 06:58:42

标签: java mysql jsp servlets

我正在创建一个基于Web的登录系统,为此我使用MySQL作为我的后端,JSPS和Servlets用于功能,还使用一个名为jasypt 1.8的库来加密密码,以便以后将它们存储在MySQL上。

我的问题是:以下代码是否有任何问题(与安全相关,最佳做法等):

 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;
}

我不知道将用户从数据库中取出然后将其与提供的密码进行比较是否正确(即我认为最好的方法是将信息从数据库使用用户名和密码,而不仅仅是前者。遗憾的是我无法做到这一点,因为我无法生成密钥,因为库中没有方法可以做到(并且我无法在文档中找到生成密钥的算法)。

我这样做是因为我使用的库有一个内置的随机盐生成器,它将自己存储在加密后创建的字符串中(如果重要的话,使用sha-256)和方法checkPassword()是唯一能够生成与数据库中存储的密钥完全相同的密钥(已经通过加密过程)。

无论如何,如果您有创建登录系统的经验或了解很多安全最佳实践,我希望您告诉我,如果您找不到合适的解决方案,您对这类问题的体验是什么。

感谢您的时间。

3 个答案:

答案 0 :(得分:1)

Jasypt确实让您可以轻松地进行此类密码检查,因此检查密码的代码非常合适。

我的主要评论是该方法中发生了两件事。

  • 获取SQL连接
  • 在控制台上打印连接消息
  • 获取用户
  • 检查它是否为空
  • 使用内部StrongPasswordEncryptor
  • 检查密码

意味着该方法中的所有内容都非常硬编码

为了让这更好,我会:

  • 使用日志记录系统Log4j
  • 将连接的配置分开到别处(属性文件...)
  • 最终使用连接池(这是MySQL
  • 的一个示例
  • 没有enpty catch块,抛出异常,或者至少记录它,所以你知道发生了什么
  • 另外,如果您想更改Jasypt options,您应该在此方法之外设置密码加密机制。

无论如何,只有少数事情使其更加模块化。

现在在生产系统中,大多数人更喜欢使用像Apache Shiro这样的框架,这样他们就可以轻松更改身份验证机制,还可以轻松配置角色和组。

瞧。希望这个答案有点轻松。

答案 1 :(得分:0)

考虑到用户名在系统中是唯一的,您阅读用户信息和比较密码哈希的解决方案是可以的,它是广泛使用的解决方案。只要整个处理在服务器端完成,就不会涉及安全风险。

但是,如果您想在实际应用中使用这样的代码,则不应每次都创建连接,而应考虑使用连接池,例如apache commons dbcp,这样可以简化开发;)

答案 2 :(得分:0)

  

还使用名为jasypt 1.8的库来加密密码

绝不能加密密码。你应该单向散列它们,并比较哈希值。您不得提供任何可以合法解释的内容,以便其他人知道用户的密码。否则,您将失去对交易的合法不可否认性,这严重到足以让您破产。你需要对此提出法律建议,这真的很严重。