JavaWeb问题记录——SessionIdGeneratorBase.createSecureRandom

JavaWeb问题记录——SessionIdGeneratorBase.createSecureRandom

摘要:本文主要记录了在启动Tomcat时,出现的一个警告以及解决办法。

部分内容来自以下博客:

https://www.jianshu.com/p/30aa8e43a396

http://hongjiang.info/jvm-random-and-entropy-source

问题重现

启动Tomcat时,后台打印警告:

1 27-Nov-2019 17:26:48.057 警告 [main] org.apache.catalina.util.SessionIdGeneratorBase.createSecureRandom Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [280] milliseconds.

Java的版本是1.8,Tomcat的版本是9.0.29。

解决办法

修改Java的配置文件

在Java的安装目录下,找到 jrelibsecurity 目录,打开 java.security 文件,找到如下配置:

1 securerandom.source=file:/dev/random

改为:

1 securerandom.source=file:/dev/./urandom

保存,然后重启Tomcat服务器即可,不建议使用这种方式,存在失败的情况。

修改Java运行环境的配置文件

在Tomcat的安装目录下,找到 bin 目录,打开 catalina.sh 文件,添加如下配置:

1 JAVA_OPTS="$JAVA_OPTS -Djava.security.egd=file:/dev/./urandom"

保存,然后重启Tomcat服务器即可,建议使用这种方式,这也是官方推荐的方式。

问题说明

从Tomcat的优化说起

在Tomcat的文档里面提到了一些启动时的优化项,其中一项是关于随机数生成时,采用了Entropy Source(熵源)的策略:

1 Tomcat 7+ heavily relies on SecureRandom class to provide random values for its session ids and in other places. Depending on your JRE it can cause delays during startup if entropy source that is used to initialize SecureRandom is short of entropy. You will see warning in the logs when this happens, e.g.:
2 <DATE> org.apache.catalina.util.SessionIdGenerator createSecureRandom
3 INFO: Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [5172] milliseconds.

意思是说,Tomcat在7以后的版本里十分依赖SecureRandom类生成的随机数来做为session ID,如果用于初始化SecureRandom的熵源是个短熵(熵不够用),那么就会报文章开头说的警告了。

熵源

熵的概念最早起源于物理学,用于度量物体的混乱程度。在信息论里面,熵用来描述不确定度。

熵源在类Unix系统中是一个特殊的设备文件,可以用作随机数发生器或伪随机数发生器,与之相关的是 /dev/random 和 /dev/urandom 。

熵源 /dev/random 是一个阻塞发生器,在读取时, /dev/random 设备会返回小于熵池噪声总数的随机字节。 /dev/random 可生成高随机性的公钥或一次性密码本。若熵池空了,对 /dev/random 的读操作将会被阻塞,直到收集到了足够的环境噪声为止。

而熵源 /dev/urandom 则是一个非阻塞的发生器,是 /dev/random 的一个副本,它会重复使用熵池中的数据以产生伪随机数据。这表示对 /dev/urandom 的读取操作不会产生阻塞,但其输出的熵可能小于 /dev/random 输出的熵。它可以作为生成较低强度密码的伪随机数生成器,不建议用于生成高强度长期密码。

Java中的相关配置

在Java的安装目录下,找到 jrelibsecurity 目录,打开 java.security 文件,里面提到了SecureRandom类使用SHA1PRNG算法或NativePRNG算法生成随机数。

在类Unix系统(比如Solaris/Linux/MacOS)上它们是基于某种特殊的熵收集设备作为种子来生成的随机数,如前面提到的 /dev/random 。

在Windows系统上,如果指定的是 file:/dev/random 或 file:/dev/urandom ,那么会使用微软的CryptoAPI作为SHA1PRNG算法的种子产生器。

通过配置 java.security.egd 和 securerandom.source 可以指定使用的熵收集设备,配置 java.security.egd 会覆盖 securerandom.source 。

官方建议

在Tomcat的文档里也给出了建议,那就是在Java的运行环境里通过设置 java.security.egd 系统属性来使用非阻塞的熵源:

1 -Djava.security.egd=file:/dev/./urandom

至于为什么是 /dev/./urandom ,而不是 /dev/urandom ,这源于Java的一个bug。大意是 /dev/urandom 在某些情况下可能还是最终会转换成调用 /dev/random 。

原文地址:https://www.cnblogs.com/shamao/p/11944619.html