您的浏览器过于古老 & 陈旧。为了更好的访问体验, 请 升级你的浏览器
Coder 发布于2021年10月30日 23:45 最近更新于 2021年10月31日 00:59

Tomcat 启动缓慢:Creation of SecureRandom instance for session ID generation using [SHA1PRNG]

2524 次浏览 读完需要≈ 2 分钟 Tomcat

WARNING [main] org.apache.catalina.util.SessionIdGeneratorBase.createSecureRandom Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [129,792] milliseconds

我在 CentOS 8 系统中安装了最新的 JDK 11.0.12 + Tomcat 9.0.54,并且将应用部署到了Tomcat中。

不过,我在启动Tomcat时,发现启动非常缓慢。

我在控制台输出的日志中发现有一行警告信息:

WARNING [main] org.apache.catalina.util.SessionIdGeneratorBase.createSecureRandom Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [129,792] milliseconds

好像有个东西在启动时耗时了120多s,请问这种问题该如何解决呢?

我在本地 Windows 系统的开发环境中启动 Tomcat,却不存在遇到这样的问题。

1 个回答

Ready · 3年前

出现这个问题的原因是,Tomcat 需要使用 SecureRandom 类的实例来生成 session ID,这个类的实例是通过调用org.apache.catalina.util.SessionIdGeneratorBase.createSecureRandom()方法来创建的。

在这个过程中,Tomcat 使用了 SHA1PRNG 算法,该算法是基于SHA-1算法实现且保密性较强的伪随机数生成器。

众所周知,伪随机数生成器需要依赖于随机种子(seed)。在 SHA1PRNG 中,有一个种子产生器,它根据配置执行各种操作。

Linux 中的随机数可以从两个特殊的文件设备中产生,一个是/dev/urandom,另外一个是/dev/random

他们产生随机数的原理是利用当前系统的熵池来计算出固定一定数量的随机bit,然后将这些bit作为字节流返回。

熵池(entropy pool),就是当前系统的环境噪音。

熵,指的是一个系统的混乱程度,系统噪音可以通过很多参数来评估,如内存的使用、文件的使用量、不同类型的进程数量等等。如果当前环境噪音变化得不是很剧烈或者当前环境噪音很小,比如刚开机的时候,而当前需要大量的随机bit,这时产生的随机数的随机效果就不是很好了(也就是说,相对就更有规律可循,也就更容易被攻击)。

Tomcat 依赖的随机数生成器会评估熵池中的噪声数量,因为随机数是从熵池中进行创建的。CentOS 平台 JDK 默认的随机数生成来源于/dev/random

当读操作时,/dev/random只返回熵池中噪声的随机字节。/dev/random非常适合那些需要非常高质量随机性的场景,比如一次性的支付或生成密钥的场景。

当熵池为空时,来自/dev/random的读操作将被阻塞,直到熵池收集到足够的环境噪声数据。这么做的目的是成为一个密码安全的伪随机数发生器,熵池要有尽可能大的输出。对于生成高质量的加密密钥或者是需要长期保护的场景,一定要这么做。

然而,默认情况下,/dev/random非常慢,因为它只从设备驱动程序和其他(慢)源收集熵。

要解决 Tomcat 因熵池不足而导致的启动阻塞问题,我们可以采取以下几种方案之一

1、通过 rng-tools 自动补充熵池(推荐)

rng-tools 可以增加内核中的熵量以使其/dev/random更快。rngd允许使用更快的熵源——主要是 TRNG(硬件随机数生成器 ),其存在于诸如 当前的 AMD / Intel 处理器、Via Nano 甚至 Raspberry Pi 等现代硬件中。

我们可以执行下面的Shell命令来安装并启用 rng-tools:

# yum 安装 rng-tools
yum install rng-tools

# 启动 rng-tools
systemctl start rngd

# 设置开机自启
systemctl enable rngd

接着,我们可以通过以下命令查看系统已收集的当前可用的熵的数量是否有所提升(不应该低于 1000)。

cat /proc/sys/kernel/random/entropy_avail
还有一个类似的增加熵量的工具,叫作 Haveged。它基于 HAVEGE 算法。Haveged 可以解决在某些情况下,系统熵过低的问题。然而,它无法保证熵的质量。如果对安全要求较高,应该优先考虑使用硬件随机数生成器 rng-tools。

2、设置Tomcat的启动参数变量

在Tomcat的启动命令行中添加如下片段:

-Djava.security.egd=file:/dev/urandom
# 如果是Java 8 之前的版本,参数值应该为"file:/dev//urandom",因为有 bug

3、修改 JVM 配置文件

$JAVA_HOME/jre/lib/security/java.security文件 中的securerandom.source=file:/dev/random改为 securerandom.source=file:/dev/urandom

注意:出于安全性考虑,推荐使用第一种方式。

已采纳 ? 0 0 0 编辑

撰写答案