2012-01-10 57 views
0

爲了給你一些背景知識,我和我的團隊正在創建一個程序,用於將用戶名和密碼存儲在數據庫中。我們使用Java並通過Java代碼與數據庫進行交互。使用Jasypt:當密碼匹配時,checkPassword方法返回false。

我們使用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:使用WHERE子句。

+0

該用戶不能使用WHERE子句「SELECT * FROM用戶」,這是因爲使用隨機鹽輸出不同 - 但每次「encryptPassword」所有valid--結果叫的。因此,考慮到他/她也正在使用此加密器來散列用戶名,因此無法生成允許在WHERE子句中使用等同運算符的值。唯一的方法是迭代它們並分別檢查每一個,就像這個用戶那樣。 – 2012-01-11 09:46:08

+0

所以,他不應該用隨機鹽生成器來加密用戶。 – sfratini 2012-04-12 04:53:30

+0

我們如何檢查數據庫中存在的值是否使用B crypt?謝謝,Neha – Prateek 2015-09-29 16:44:40

1

我是jasypt的作者。

從您的消息中,我不清楚在匹配用戶名或密碼時是否觀察到此問題 - 您說'試圖檢查明文用戶名與加密密碼',這是沒有意義的 - 。儘管如此,像你這樣的問題最常見的原因之一是你的數據庫列不夠大,無法存儲散列的用戶名和/或密碼。

散列結果的大小將取決於正在使用的算法和鹽配置,但對於使用MD5和8字節鹽大小的BasicPasswordEncryptor,您應該期望您的散列爲16字節(散列)加上8個字節(鹽),再加上8個額外的字節,因爲文本Base64編碼。總共有32個字節。

也認爲,在許多字符DBMS措施VARCHAR字段,而不是字節,所以你應該做在你的餐桌,根據使用的字符編碼此時,相應的轉換。

我總是建議首先檢查列的大小,因爲如果你嘗試存儲爲varchar是太長列--they簡單地截斷了很多的DBMS不會引發錯誤。我不知道MySQL的行爲,但甲骨文完全是這樣做的。當你試圖解密它時......它不匹配。

所以,檢查你列的大小可能是一個很好的起點。並記住jasypt有一個用戶論壇http://forum.jasypt.org

哦,順便說一句 - 原諒我,如果這只是特別的演示代碼,但以防萬一:您應該確保關閉所有的Statement和ResultSet對象在'finally'塊中重用它們之前......所以你應該在內部迭代塊中使用不同的'statement'和'rs'變量,並且每次都關閉它們。

問候。因爲他/她正在使用BasicPasswordEncryptor,

相關問題