1

为了给你一些背景知识,我和我的团队正在创建一个将用户名和密码存储在数据库中的程序。我们正在使用 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;
    }

}
4

2 回答 2

1

我是 jasypt 的作者。

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

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

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

我总是建议首先检查列大小,因为如果您尝试存储对于列来说太长的 varchar,许多 DBMS 不会引发错误——它们只是截断它。我不知道 MySQL 的行为,但 Oracle 正是这样做的。当您尝试将其解密时……它不匹配。

因此,检查您的列大小可能是一个很好的起点。记住 jasypt 在http://forum.jasypt.org有一个用户论坛

哦,顺便说一句——如果这只是临时演示代码,请原谅我,但以防万一:你应该确保在重用它们之前关闭所有 Statement 和 ResultSet 对象在“finally”块中......所以你应该在内部迭代块中使用不同的 'statement' 和 'rs' 变量,并且每次都关闭它们。

问候。

于 2012-01-11T09:37:15.447 回答
-1

Optimisation 1 : Use a WHERE clause.

于 2012-01-10T18:50:37.410 回答