是jBCrypt 0.3线程安全吗?

时间:2010-10-16 15:06:41

标签: java thread-safety

问题说的都是真的。代码可以在以下链接中找到 - > http://www.mindrot.org/projects/jBCrypt/

3 个答案:

答案 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日,以下内容有更多反对意见