使用Jasypt:当密码匹配时,checkPassword方法返回false。

时间:2012-01-10 18:40:11

标签: sql database encryption jasypt

为了给你一些背景知识,我和我的团队正在创建一个程序,用于在数据库中存储用户名和密码。我们正在使用Java并通过Java代码与数据库交互。

我们使用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;
    }

}

2 个答案:

答案 0 :(得分:1)

我是jasypt的作者。

从您的消息中,我不清楚您在匹配用户名或密码时是否正在观察此问题 - 您说'尝试使用加密密码检查明文用户名',这没有任何意义 - - 。然而,像您这样的问题最常见的原因之一是您的数据库列不够大,无法存储您的哈希用户名和/或密码。

散列结果的大小取决于所使用的算法和salt配置,但对于使用MD5和8字节的salt大小的BasicPasswordEncryptor,您应该期望散列为16字节(散列)加上8个字节(盐),加上8个额外字节,因为文本Base64编码。总共32个字节。

还要认为很多DBMS在字符中测量varchar字段而不是字节,因此您应该根据表中使用的字符编码进行适当的转换。

我总是建议首先检查列大小,因为如果您尝试存储对于列来说太长的varchar,许多DBMS不会引发错误 - 它们只是截断它。我不知道MySQL的行为,但Oracle确实如此。当你试图解密它时...它不匹配。

因此,检查色谱柱尺寸可能是一个很好的起点。请记住jasypt在http://forum.jasypt.org

有一个用户论坛

哦,顺便说一下 - 请原谅我,如果这只是特定的演示代码,但为了以下情况:你应该确保在重复使用之前关闭'finally'块中的所有Statement和ResultSet对象。所以你应该在内部迭代块中使用不同的'statement'和'rs'变量,并且每次都关闭它们。

问候。

答案 1 :(得分:-1)

优化1:使用WHERE子句。