2011-08-24 65 views
4

我正在创建一个基于Web的登录系统,为此我使用MySQL作为后端,JSPS和Servlets的功能也使用名为jasypt 1.8的库来加密密码,以便稍后将它们存储在MySQL上。使用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()是唯一能够生成与存储在数据库中的密钥完全相同的密钥(已经通过加密过程)的方法。

无论如何,如果您有任何创建登录系统的经验或知道很多安全最佳实践,我希望您告诉我,如果您没有找到适合我的解决方案的经验,那么您会遇到什么样的问题。

谢谢你的时间。

回答

1

Jasypt正是让你轻松做到这种密码检查,所以检查密码的代码是相当好的。

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

  • 得到一个SQL连接
  • 打印连接消息控制台
  • 上得到一个用户
  • 检查它不为空
  • 具有内部StrongPasswordEncryptor

检查密码这意味着一切都非常硬编码

为了使这更好,我想:

  • 利用测井系统的Log4j
  • 分开连接其他地方的配置(属性文件...)
  • 最终使用连接池(在这里是一个例如,对于MySQL
  • 没有一个enpty catch块,抛出异常,或者至少记录它,所以你知道发生了什么
  • 此外,如果你想改变你的Jasypt options,你建议立即进行删除d在这个方法之外建立密码加密机制。

总之,只有几件事情,使之更加模块化。

现在在生产系统中,大多数人都喜欢使用像Apache Shiro一个框架,这样他们就可以很容易地改变身份验证机制,而且,很容易地配置角色和组。

瞧。希望这个答案流露出一点点亮光。

+0

出色答卷,我从来没有想过使用连接池阅读此之前,立即执行,并I'm无疑使这个更加模块化这仅仅是一个概念,我为我自己做证明,以便我能得到一些反馈是什么需要重做,只是多了一个问题:当你说我需要单独连接到属性文件的配置,你指的是使用一个新的类呢?或者使用某种文本文件从中读取数据?再次感谢您的反馈。 –

+0

除了上述很好的建议,我建议在您的查询只选择密码字段,因为它是你使用的唯一一个。您可以避免传输未使用的数据并降低带宽使用量。 –

+0

@ user815922是的,一个文本文件。 Jasypt有一些[外部化配置和阅读它的例子](http://www.jasypt.org/encrypting-configuration.html)。 –

0

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

但是,如果你想在实际应用中使用这样的代码,你不应该建立连接的每个时间,但考虑使用连接池,如Apache公共DBCP,这还简化了开发;)

0

也使用一个名为jasypt 1.8的库来加密密码

绝不能加密密码。你应该单向散列它们,并比较散列。您不得提供任何可以被合法解释为让别人知道用户密码的方式。否则,您将失去交易的法律不可否认性,而且这严重到足以让您失去业务。你需要就此采取法律建议,这真的很严重。

+0

对不起,我猜我误解了加密的概念,Jasypt的库实际上做的是单向散列每个密码(大约有5000次迭代的SHA-256方法),之后它存储在MySQL DB中,之后checkPassword()方法(同样来自Jasypt的库)检查存储在已有的单向散列密码中的salt,并生成密码并将其与DB中的密码进行比较以检查它们是否相等,请告诉我,如果我做错了。 –

相关问题