2012-01-10 15 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

このユーザーはBasicPasswordEncryptorを使用しているため、 'select * from Users'でWHERE句を使用できません。これは、 'encryptPassword'が呼び出されるたびにランダムな塩分出力を使用するため、すべての有効な結果が使用されるためです。したがって、この暗号化プログラムを使用してユーザー名をハッシュしていることを考えると、WHERE句で等価演算子を使用できる値を生成する方法はありません。唯一の方法は、これらのすべてを反復して、このユーザーが行うように、それぞれを個別にチェックすることです。 –

+0

だから、彼はランダムな塩生成装置でユーザーを暗号化すべきではありません。 – sfratini

+0

データベースに存在する値がハッシュされているかどうか、またはB暗号を使用していないかどうかを確認する方法はありますか?ありがとう、Neha – Prateek

1

私はjasyptの作者です。

あなたのメッセージから、ユーザー名またはパスワードを照合する際にこの問題を遵守しているかどうかはわかりません。「暗号化されたパスワードに対して平文のユーザー名を確認しようとしています。 - 。それにもかかわらず、あなたのような問題の最も一般的な理由の1つは、データベースの列がハッシュされたユーザー名やパスワードを格納するために十分に大きくないことです。

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

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

列のサイズが長すぎるvarcharを格納しようとすると、多くのDBMSでエラーが発生しないため、列サイズを最初にチェックすることをお勧めします。私はMySQLの動作を知らないが、Oracleはこれを正確に実行する。それを元に戻すと...一致しません。

このように、列のサイズを確認することは良い出発点です。そして、jasyptがユーザフォーラムを持っていることを覚えておいてください。http://forum.jasypt.org

ああ、それはちょっと特別なデモコードだと私に許してください。ただの場合は、すべてのStatementとResultSetオブジェクト'finally'ブロックを再利用する前に...内部の反復ブロックで異なる 'statement'と 'rs'変数を使用し、その都度閉じる必要があります。

よろしくお願いいたします。

関連する問題