2011-08-24 18 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中的密碼進行比較以檢查它們是否相等,請告訴我,如果我做錯了。 –

相關問題