BCrypt性能恶化 [英] BCrypt performance deterioration

查看:454
本文介绍了BCrypt性能恶化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们在Jboss服务器6.1中运行了三个Web应用程序(标准的Spring MVC-Hibernate)。所有这三个应用程序共享一个通用的身份验证方法,该方法被编译为JAR并包含在每个WAR文件中。我们的身份验证方法使用org.springframework.security.crypto.bcrypt.BCrypt来哈希用户密码,请参阅下面的内容:

We have three web applications (standard Spring MVC-Hibernate) running within a Jboss server 6.1. All three applications share a common authentication method which is compiled as a JAR and included within each WAR file. Our authentication method uses org.springframework.security.crypto.bcrypt.BCrypt to hash user passwords, please see below:

hashedPassword.equals(BCrypt.hashpw(plainTextPassword, salt));

JBOSS启动选项

设置JAVA_OPTS = -Xms2048m -Xmx4096m -XX:PermSize = 256m -XX:MaxPermSize = 512m -XX:+ HeapDumpOnOutOfMemoryError -verbosegc -XX:+ PrintGCTimeStamps -XX:+ PrintGCDetails -Xloggc:gc.txt -XX:+ UseParallelOldGC

问题:
当服务器重新启动时, Bcrypt.hashpw需要100ms才能解密密码。但是经过一段时间(没有模式),Bcrypt.hashpw的性能突然从100ms上升到10s秒。没有明显的原因。

Problem: It appears that when the server is restarted, the Bcrypt.hashpw takes 100ms to decrypt password. However after some time (there is no pattern) suddenly the Bcrypt.hashpw performance spikes up from 100ms to 10s of seconds. There is no obvious reason for this.

更多信息:


  • Hibernate版本:4.2.4.Final

  • Spring版本:4.0.5.RELEASE Spring

  • 安全版本:3.2.4.RELEASE

之前有没有其他人看过这个问题?

Has anyone else seen this problem before?

推荐答案


问题:当服务器出现时重启,Bcry pt.hashpw需要
100ms来解密密码。但是经过一段时间(没有模式)
突然之后,Bcrypt.hashpw的性能从100毫秒增加到10秒。
没有明显的理由。

Problem: It appears that when the server is restarted, the Bcrypt.hashpw takes 100ms to decrypt password. However after some time (there is no pattern) suddenly the Bcrypt.hashpw performance spikes up from 100ms to 10s of seconds. There is no obvious reason for this.

问题是 / dev / random 有时阻止它,当它发生时它似乎是随机的:)更令人困惑的是,当试图测试它是如何工作的时候你会遇到观察者效应,即在尝试观察随机行为时你'重新产生熵,这可能导致大量混乱,即我的结果与你的结果不一样等。这也是为什么看起来没有模式..

The problem is /dev/random sometimes blocks and when it does it will appear to be random :) The more confusing thing is that while trying to test how it works you'll run up against the Observer Effect ie while trying to observe random behavior you're generating entropy and this can lead to a ton of confusion i.e. my results won't be the same as yours etc. This is also why it looks like there's no pattern..

我将演示该问题并向您展示如何在您自己的服务器上重新创建它(因此在内),以便您可以测试解决方案。我会尝试提供一些修复,请注意这是在Linux上,但同样的问题将发生在需要熵生成随机数并耗尽的任何系统上。

I'll demonstrate the problem and show you how to recreate it (within reason) on your own servers so you can test solutions. I'll try and provide a couple of fixes, note this is on Linux but the same problem will happen on any system that requires entropy to generate random numbers and runs out.

在Linux上 / dev / random 是一个随机字节流。当你从
流中读取时,你耗尽了可用的熵。当它达到某一点时,
/ dev / random 块读取。您可以使用此命令查看可用的熵

On Linux /dev/random is a stream of random bytes. As you read from the stream you deplete the available entropy. When it reaches a certain point reads from /dev/random block. You can see available entropy using this command

cat /proc/sys/kernel/random/entropy_avail

如果您运行以下bash脚本并监控 entropy_avail 您将获得
注意到当bash脚本使用它时,熵会急剧下降。

If you run the following bash script and also monitor entropy_avail you'll notice that entropy dips dramatically as the bash script consumes it.

while :
do
  cat /dev/random > /dev/null
done

这也应该给你一个关于如何重新创建这个的提示你的服务器上的问题,即运行上面的bash脚本来减少可用的熵,问题就会出现。

This should also give you a hint on how to recreate this problem on your servers ie run the above bash script to reduce available entropy and the problem will manifest itself.

如果你想看到你的系统每秒有多少字节创建你
可以使用 pv 来衡量它,即

If you want to see just how many bytes per second your system is creating you can use pv to measure it i.e.

pv /dev/random

如果你离开 pv 运行它有效,它消耗随机字节流,这意味着其他服务可能会开始阻塞。请注意, pv 也显示它的输出,因此它可能也会增加系统上的可用性:)。

If you leave pv running it has an effect, it's consuming the random stream of bytes which means other services might start to block. Note that pv is also displaying it's output so it might also be increasing available entroy on the system :).

在使用 pv / dev / random 的很少或没有熵的系统上看起来似乎很慢。我也经历过VM有时会产生熵的主要问题。

On systems with little or no entropy using pv /dev/random will seem glacially slow. I've also experienced that VM's sometimes have major issues with generating entropy.

要重新创建问题,请使用以下类......

To recreate the issue use the following class...

import java.security.SecureRandom;
import org.mindrot.jbcrypt.BCrypt;
public class RandTest {
    public static void main(String[] args) {
        SecureRandom sr = new SecureRandom();
        int out = 0;
        String password = "very-strong-password-1729";
        String hashed;
        for (int i = 0; i < 200000 ; i++) {
            hashed = BCrypt.hashpw(password, BCrypt.gensalt());
            //If we print, we're generating entroy :) System.out.println(hashed);
        }
    }
}

我将bcrypt下载到本地目录。我编译并运行如下

I downloaded bcrypt to a local directory. I compiled and ran it as follows

javac -cp ./jBCrypt-0.4/src/   RandTest.java
java  -cp ./jBCrypt-0.4/src/:. RandTest

如果你在运行 RandTest时运行之前的bash脚本你会看到系统阻塞等待更多熵的大停顿。如果您运行 strace ,您将看到以下内容......

If you then run the bash script from earlier while runnng RandTest you'll see large pauses where the system is blocking waiting for more entropy. If you run strace you'll see the following...

1067 [pid 22481] open("/dev/random", O_RDONLY|O_LARGEFILE) = 12
11068 [pid 22481] fstat64(12, {st_mode=S_IFCHR|0666, st_rdev=makedev(1, 8), ...}) = 0
11069 [pid 22481] fcntl64(12, F_GETFD)        = 0
11070 [pid 22481] fcntl64(12, F_SETFD, FD_CLOEXEC) = 0
.....
11510 [pid 22481] read(12, "\320\244\317RB\370", 8) = 6

该程序正在读取 / dev / random 。测试熵的问题是
你可能会在尝试测试它时产生更多,即观察者效应。

The program is reading from /dev/random. The problem with testing entropy is you might be generating more of it while trying to test it ie the Observer Effect.

修正

第一个修复是从使用 / dev / random 更改为 / dev / urandom ie

The first fix is to change from using /dev/random to /dev/urandom ie

time java  -Djava.security.egd=file:///dev/./urandom -cp ./jBCrypt-0.4/src/:.  RandTest

另一种解决方法是重新创建 / dev / random 设备作为 / dev / urandom 设备。您可以在手册页中找到如何执行此操作,而不是创建它们...

An alternative fix is to recreate the /dev/random device as a /dev/urandom device. You can find how to do this form the man page ie, instead of creating them...

mknod -m 644 /dev/random c 1 8
mknod -m 644 /dev/urandom c 1 9
chown root:root /dev/random /dev/urandom

我们删除一个并伪造它,即

we delete one and fake it ie

rm /dev/random
mknod -m 644 /dev/random c 1 9
chown root:root /dev/random

/ dev / random 现在实际上是 / dev / urandom

要记住的关键是要测试随机数据,这些数据需要从你正在测试的
系统中获取,因为观察者效应很难。

The key thing to remember is testing random data that requires entroy from the system you're testing on is difficult because of the Observer Effect.

这篇关于BCrypt性能恶化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆