Play 2.1で、BCryptを使用して認証を実装しようとしています。 Javaアプリケーションですが、Invalid salt version exception
ユーザーを認証しようとしているとき。
これは私のスタックトレースです
play.api.Application$$anon$1: Execution exception[[IllegalArgumentException: Invalid salt version]]
at play.api.Application$class.handleError(Application.scala:289) ~[play_2.10.jar:2.1.0]
at play.api.DefaultApplication.handleError(Application.scala:383) [play_2.10.jar:2.1.0]
at play.core.server.netty.PlayDefaultUpstreamHandler$$anon$2$$anonfun$handle$1.apply(PlayDefaultUpstreamHandler.scala:132) [play_2.10.jar:2.1.0]
at play.core.server.netty.PlayDefaultUpstreamHandler$$anon$2$$anonfun$handle$1.apply(PlayDefaultUpstreamHandler.scala:128) [play_2.10.jar:2.1.0]
at play.api.libs.concurrent.PlayPromise$$anonfun$extend1$1.apply(Promise.scala:113) [play_2.10.jar:2.1.0]
at play.api.libs.concurrent.PlayPromise$$anonfun$extend1$1.apply(Promise.scala:113) [play_2.10.jar:2.1.0]
Java.lang.IllegalArgumentException: Invalid salt version
at org.mindrot.jbcrypt.BCrypt.hashpw(BCrypt.Java:664) ~[jbcrypt-0.3m.jar:na]
at org.mindrot.jbcrypt.BCrypt.checkpw(BCrypt.Java:763) ~[jbcrypt-0.3m.jar:na]
at model.operations.DistrictOperations.authenticate(DistrictOperations.Java:24) ~[na:na]
at controllers.Application.authenticateDistrict(Application.Java:26) ~[na:na]
at Routes$$anonfun$routes$1$$anonfun$applyOrElse$2$$anonfun$apply$2.apply(routes_routing.scala:133) ~[na:na]
at Routes$$anonfun$routes$1$$anonfun$applyOrElse$2$$anonfun$apply$2.apply(routes_routing.scala:133) ~[na:na]
私は次のMavenリポジトリを使用しています: http://mvnrepository.com/artifact/org.mindrot/jbcrypt/0.3m
私のコードはドキュメントに基づいているため、
district.setPassword(BCrypt.hashpw(json.findPath("password").getTextValue(), BCrypt.gensalt()));
パスワードを保存するため(パスワードがnullかどうかもチェックしています)
BCrypt.checkpw(password, d.getPassword());
入力されたパスワードが正しいかどうかをチェックするため。ここで、passwordはStringで、d.getPassword()はハッシュされたパスワードです。
これが関連情報かどうかはわかりませんが、正確にはORMにはhibernateを、DBにはPostgreSQL 8.4を使用しています。
私はここに閉じ込められているので、誰かが私を助けてくれるかどうか尋ねています。よろしくお願いします。
この質問にご迷惑をおかけして申し訳ありません。 BCryptedではなくDBにプレーン文字列を保存するコードにバグが1つだけありました。コードの他の部分から全体が呼び出されました。
同じ例外が発生する他のユーザーについては、BCrypt.checkpw
パラメータが正しい方法で設定されていることを確認してください。 (私の愚かな間違いに気づく前に私はこの質問を見つけなかったので見つけました。)
または、OPが自分自身で答えたときに、ハッシュされたパスワードの値をログ/デバッグして、実際にハッシュされたパスワードを比較していることを再確認します! $2a$10$llw0G6IyibUob8h5XRt9xuRczaGdCm/AiV6SSjf5v78XS824EGbh.
の形式の60文字の文字列である必要があります
同じ問題が発生しました。パスワードがプレーンテキストではなくハッシュ形式でデータベースに保存されていることを確認してください。これが Bcryptジェネレータ で、プレーンテキストのパスワードをBcryptハッシュに変換します。
jBcryptは古すぎて、実際にはメンテナンスされていません。新しい$2y$
バージョンを処理するには、そのライブラリの新しい実装に切り替えることを検討してください。
私はこの純粋なJavaライブラリ https://github.com/patrickfav/bcrypt を使用してこれを解決し、現在のScala =プロジェクト。
次の関数を使用して、VERSION_2Y
で作成されたハッシュを最終的に確認できます。
/**
* Verifies an encrypted password against the expected value
*
* @link https://github.com/patrickfav/bcrypt
* @param hash The hashed password (encypted with BCrypt version $2Y$)
* @param password The unencrypted password string
*/
private def verifyBcryptHash(hash: String, password: String): Boolean = {
if (hash == null || hash.trim.isEmpty)
false
else
BCrypt
.verifyer()
.verifyStrict(
password.toCharArray(),
hash.toCharArray(),
BCrypt.Version.VERSION_2Y
)
.verified
}
最初の引数がプレーンテキストであり、2番目の引数がハッシュされたパスワードであることを確認する必要があります。これは関数の宣言です:
public static boolean checkpw(String plaintext, String hashed)
checkpw(password, hash)
に渡した「ハッシュ」値が解読可能な値でない場合、BCryptはこの赤いニシンを投げるようです