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 の作者です。

あなたのメッセージからは、ユーザー名またはパスワードを照合するときにこの問題が発生しているかどうかはわかりません.「暗号化されたパスワードに対してプレーンテキストのユーザー名をチェックしようとしている」と言っていますが、これは意味がありません. それにもかかわらず、あなたのような問題の最も一般的な理由の 1 つは、データベースの列がハッシュされたユーザー名やパスワードを格納するのに十分な大きさではないことです。

ハッシュ結果のサイズは、使用されているアルゴリズムとソルト構成によって異なりますが、MD5 と 8 バイトのソルト サイズを使用する BasicPasswordEncryptor の場合、ハッシュは 16 バイト (ハッシュ) と 8 バイト ( salt) に加えて、テキストの Base64 エンコーディングのために 8 バイトが追加されます。合計 32 バイト。

また、多くの DBMS は varchar フィールドをバイト単位ではなく文字単位で測定するため、テーブルで使用されている文字エンコーディングに応じて適切な変換を行う必要があります。

列に対して長すぎる varchar を格納しようとしても、多くの DBMS ではエラーが発生せず、単純に切り捨てられるため、最初に列のサイズを確認することを常にお勧めします。MySQL の動作はわかりませんが、Oracle はまさにこれを行います。そして、それを解読しようとすると... 一致しません。

したがって、列のサイズを確認することは、良い出発点になる可能性があります。また、jasypt にはhttp://forum.jasypt.orgにユーザー フォーラムがあることを思い出してください。

ところで、これがアドホックなデモ コードである場合はご容赦ください。ただし、念のため: Statement オブジェクトと ResultSet オブジェクトを再利用する前に、'finally' ブロックですべて閉じる必要があります。内側の反復ブロックで異なる 'statement' 変数と 'rs' 変数を使用し、毎回それらを閉じる必要があります。

よろしく。

于 2012-01-11T09:37:15.447 に答える
-1

最適化1:WHERE句を使用します。

于 2012-01-10T18:50:37.410 に答える