问题说的都是真的。代码可以在以下链接中找到 - > http://www.mindrot.org/projects/jBCrypt/
答案 0 :(得分:13)
我强烈不同意现有的答案和目前接受的答案。
在简要回顾一下jBcrypt的源代码后,我很满意它是线程安全的。创建的唯一实例不会转义键hashpw
静态方法的范围,并且不会通过我可以看到的任何机制将其字段与任何其他实例共享。
此外,我对真的对由静态方法组成的API的抱怨感到困惑。散列函数是纯粹的,因此没有理由不通过静态方法提供它们。我真的很高兴没有可用的用户空间访问实例方法,以免一些傻瓜尝试做一些聪明的事情(比如一遍又一遍地使用一个实例,“重置”它以最小化分配/ GC或一些这样的愚蠢)。 / p>
答案 1 :(得分:4)
恢复这个老问题,因为我相信当前的答案是错误的,并且这个帖子在谷歌搜索中突然出现。
查看代码并运行了几个简单的测试。 jbcryt似乎是线程安全的。
在代码中: - 尽管它主要是静态方法,但这些方法会创建bcrypt类的实例,以便在需要时进行计算。
测试样品: -had bcrypt不是线程安全的,我本来期望这些方法中的任何一种都会抛出某种形式的错误,但他们没有。
@Test
public void multiThreadHash() throws InterruptedException{
List<Thread> threads = new ArrayList<Thread>();
for(int i = 0; i<40; i++){
threads.add(new Thread(){
@Override
public void run() {
long start = System.currentTimeMillis();
while(System.currentTimeMillis()<start+12000){
String password = "sample";
String hash = BCrypt.gensalt(4);
String hashed = BCrypt.hashpw(password, hash);
}
}
});
}
for(Thread t: threads){
t.start();
}
Thread.sleep(12200L);
}
@Test
public void multiThreadReproductibleHash() throws InterruptedException{
List<Thread> threads = new ArrayList<Thread>();
for(int i = 0; i<40; i++){
threads.add(new Thread(){
@Override
public void run() {
long start = System.currentTimeMillis();
while(System.currentTimeMillis()<start+12000){
String password = "sample";
String hash = "$2a$04$/YkrS2ifyAloNVUk5qAO7O";
String expected = "$2a$04$/YkrS2ifyAloNVUk5qAO7OlqIsp2ECTMDinOij9wvn7nXPRJCo8Gy";
String hashed = BCrypt.hashpw(password, hash);
Assert.assertEquals(expected, hashed);
}
}
});
}
for(Thread t: threads){
t.start();
}
Thread.sleep(12200L);
}
答案 2 :(得分:2)
首先,它没有记录为线程安全的,所以对于所有意图和目的,它不是。并且,在进一步调查中,它绝对不是:事实证明,虽然有一些实例字段,但没有BCrypt暴露的实例;它试图通过静态方法完成所有事情。它可能不是线程安全的。它足够小,假设你关心并且作者会接受,你可以提供一个补丁来轻松转换它以提供单独的,安全的实例(编辑添加:我已经仔细擦洗它并准备了一个更清洁的版本,我将发送到作者......)
其次,您希望以何种方式在多线程环境中使用它?我不清楚你想在不同的线程中做什么。
注意:截至2013年7月18日,以下内容有更多反对意见