Java BCrypt.checkpw() 无效的盐版本异常
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16478604/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
BCrypt.checkpw() Invalid salt version exception
提问by ziky90
I'm trying to implement authentication using BCrypt, in my Play 2.1. Java application, but I'm getting Invalid salt version exception
when I'm trying to authenticate the user.
我正在尝试在 Play 2.1 中使用 BCrypt 实现身份验证。Java 应用程序,但是Invalid salt version exception
当我尝试对用户进行身份验证时却遇到了问题。
This is my stack trace
这是我的堆栈跟踪
play.api.Application$$anon: 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$$anonfun$handle.apply(PlayDefaultUpstreamHandler.scala:132) [play_2.10.jar:2.1.0]
at play.core.server.netty.PlayDefaultUpstreamHandler$$anon$$anonfun$handle.apply(PlayDefaultUpstreamHandler.scala:128) [play_2.10.jar:2.1.0]
at play.api.libs.concurrent.PlayPromise$$anonfun$extend1.apply(Promise.scala:113) [play_2.10.jar:2.1.0]
at play.api.libs.concurrent.PlayPromise$$anonfun$extend1.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$$anonfun$applyOrElse$$anonfun$apply.apply(routes_routing.scala:133) ~[na:na]
at Routes$$anonfun$routes$$anonfun$applyOrElse$$anonfun$apply.apply(routes_routing.scala:133) ~[na:na]
I'm using following maven repository: http://mvnrepository.com/artifact/org.mindrot/jbcrypt/0.3m
我正在使用以下 maven 存储库:http: //mvnrepository.com/artifact/org.mindrot/jbcrypt/0.3m
My code is based on the documentation, thus
我的代码基于文档,因此
district.setPassword(BCrypt.hashpw(json.findPath("password").getTextValue(), BCrypt.gensalt()));
For saving the password (I'm also checking the password for being null)
用于保存密码(我也在检查密码是否为空)
BCrypt.checkpw(password, d.getPassword());
For checking if the entered password is correct, where password is String and d.getPassword() is hashed password.
用于检查输入的密码是否正确,其中 password 是 String 并且 d.getPassword() 是散列密码。
I don't know if this is relevant information, but to be precise I'm using hibernate for ORM and PostgreSQL 8.4 as DB.
我不知道这是否是相关信息,但准确地说,我使用 Hibernate for ORM 和 PostgreSQL 8.4 作为 DB。
I'm kind of stuck in here so I'm asking if anyone could help me out. Than you very much in advance.
我有点被困在这里,所以我问是否有人可以帮助我。比你提前很多。
采纳答案by ziky90
I'm very sorry for bothering with this question. I had just one bug in the code that was saving plain string to the DB instead of the BCrypted one. It was whole called from some other part of code.
我很抱歉打扰这个问题。我在代码中只有一个错误,它将纯字符串保存到数据库而不是 BCrypted 一个。它完全是从代码的其他部分调用的。
回答by flurdy
For others encountering the same exception, check that you have the BCrypt.checkpw
parameters the right way round. (I didn't and therefore found this question before I realised my silly mistake.)
对于遇到相同异常的其他人,请检查您的BCrypt.checkpw
参数是否正确。(我没有,因此在我意识到我的愚蠢错误之前发现了这个问题。)
Or as the OP answered himself, log/debug the value of the hashed password to double check you are actually comparing a hashed password! It should be a 60-char string in the format
$2a$10$llw0G6IyibUob8h5XRt9xuRczaGdCm/AiV6SSjf5v78XS824EGbh.
或者当 OP 自己回答时,记录/调试散列密码的值以仔细检查您实际上是在比较散列密码!它应该是格式为 60 个字符的字符串
$2a$10$llw0G6IyibUob8h5XRt9xuRczaGdCm/AiV6SSjf5v78XS824EGbh.
回答by Ben
I encountered the same problem; Make sure your password is stored in the database in hashed format instead of plain text. Here is a Bcrypt generatorto translate your plain text password into a Bcrypt hash.
我遇到了同样的问题;确保您的密码以散列格式而不是纯文本格式存储在数据库中。这是一个Bcrypt 生成器,可将您的纯文本密码转换为 Bcrypt 哈希。
回答by Ouissal
You have to make sure that the first argument is the plaintext and the second one is the hashed password. This is the function's declaration :
您必须确保第一个参数是明文,第二个是散列密码。这是函数的声明:
public static boolean checkpw(String plaintext, String hashed)
回答by Black
BCrypt seems to throw this red herring if the 'hash' value you pass in to checkpw(password, hash)
isn't even a decipherable value
如果您传入的“哈希”值checkpw(password, hash)
甚至不是可破译的值,那么 BCrypt 似乎会抛出这个红鲱鱼
回答by sentenza
jBcrypt is too old and actually unmaintained. Please consider switching to a new implementation of that library to handle the new $2y$
versions.
jBcrypt 太旧了,实际上没有维护。请考虑切换到该库的新实现来处理新$2y$
版本。
I solved this using this pure Java library https://github.com/patrickfav/bcrypt, adding it in my current Scala project.
我使用这个纯 Java 库https://github.com/patrickfav/bcrypt解决了这个问题,并将它添加到我当前的 Scala 项目中。
With the following function I can finally verify the hashes created with VERSION_2Y
:
使用以下函数,我最终可以验证使用以下方法创建的哈希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 Y$)
* @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
}