2

開発目的でパスワードをプレーンテキストで保存していますが、代わりにハッシュの保存を開始したいのですが、次のSecurityExceptionのために、ハッシュ化されたパスワードに対してGlassFishを適切に認証することにまだ成功していません。

SEVERE: jdbcrealm.invaliduserreason
WARNING: WEB9102: Web Login Failed: com.sun.enterprise.security.auth.login.common.LoginException: Login failed: Security Exception

まず、GlassFish 3.1を実行しており、JDBCレルムのダイジェストをSHA-256に設定しました。

Userのクラスには、次の注釈付きパスワードフィールドがあります。

@Basic(fetch = FetchType.LAZY)
@Column(length = 45, nullable = false)
private String password;

次のヘルパーメソッドは、パスワードのハッシュを担当します。

private byte[] digest(String input) {
    byte[] output = null;
    try {
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        output = md.digest(input.getBytes("UTF-8"));
    } catch (NoSuchAlgorithmException ex) {
        Logger.getLogger(RegistrationController.class.getName()).log(Level.SEVERE, null, ex);
    } catch (UnsupportedEncodingException ex) {
        Logger.getLogger(RegistrationController.class.getName()).log(Level.SEVERE, null, ex);
    }
    return output;
}

次に、ユーザーに次のようにパスワードを設定します。

u.setPassword(Base64.encode(digest(password)).toString());

これは文書化されていないように見えるため、Base64でエンコードしませんでしたが、この質問:Glassfishセキュリティ-jdbcRealm:SHA-256ダイジェストでログインを構成する方法は、そうする必要があることを示唆しています。

したがって、私が知りたいのは、GlassFishがデータベースのパスワードフィールドとして文字列(VARCHAR)またはbyte [](BLOB)を期待しているのか、パスワードを正しくハッシュしているのか、さらにBase64エンコードするのが正しいのかということです。パスワードハッシュ?

ありがとう!

4

1 に答える 1

2

GlassFishは、データベースのパスワードフィールドとして文字列(VARCHAR)またはbyte [](BLOB)を想定していますか?

JDBCのJavaタイプにマップする列が必要java.lang.Stringであり、通常はCHAR、VARCHARなどです。JDBCレルムの実装がResultSet.getStringメソッド呼び出し呼び出しを発行してパスワードハッシュを取得するため、LOBは機能しません。

パスワードを正しくハッシュしていますか?さらにBase64でパスワードハッシュをエンコードするのは正しいですか?

サポートされているオプションはBase64エンコーディングだけではありません。16進エンコーディングも実行できます。ただし、これらのいずれかを実行し、実行時に同じように実行するようにJDBCレルムを構成する必要があります。エンコーディングパラメータがない場合、Glassfishはダイジェストに関連付けられたバイトシーケンスcharsetを、レルム用に設定された文字のシーケンスに変換します。

この問題は、式でのUTF-8エンコーディングの言及に関係していると思われますinput.getBytes("UTF-8")。メソッドによって提供される結果のBase64エンコーディングがdigest、データベースに保存されているパスワードハッシュと実際に一致するかどうかを確認する価値があります。

また、失敗の理由がであると考えるとjdbcrealm.invaliduserreason、次の条件のいずれかが当てはまる可能性もあります。

  • JDBCレルムにはエンコーディングパラメータが指定されていません。base64またはのいずれかであることが望ましいですhex(JDBCレルムのソースコードを使用する場合は問題ありません)。そうでない場合、ダイジェストバイト配列が文字配列に変換されるシナリオになります(私の意見ではユーザーが提供するパスワードが常に特定のエンコーディングであることを保証できない限り、少し不安定です)。
  • データベース内のユーザーのパスワードハッシュは存在しません。実行されたSQLクエリに関する以前の回答を参照してください。自分でクエリを実行することをお勧めします。derby.propertiesDerbyデータベースの場所にプロパティを含む名前のファイルを配置することにより、Derbyによって発行されたステートメントをログに記録できます(データベースとして使用している場合)derby.language.logStatementText=true。データベースをシャットダウンすると、derby.logファイルにアプリケーションサーバーによって発行されたすべてのクエリが入力されます。
  • Glassfishによって作成されたSQLステートメントが正しくありません。
  • データベースへの接続を確立できませんでした。
于 2011-07-28T19:57:10.603 に答える