2012-01-10 35 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,

相关问题