Linux服务器中SecureRandom生成随机数非常慢,NativePRNG$Blocking 阻塞
问题描述:
使用华为obs的sdk创建client,在mac和Windows环境本地调试完成,发到测试环境的Linux服务器却非常慢,定位到具体代码是:
java.security.SecureRandom.next(SecureRandom.java:505)
问题原因:
SecureRandom类使用了多种熵源来生成随机数,包括操作系统提供的随机性源、硬件随机数生成器和其他可用的随机性源。这种多样化的熵源提供了更高的随机性和抵抗性,使得生成的随机数更难以预测和破解。
SecureRandom支持多种随机数生成算法,包括伪随机数生成器(PRNG)和真随机数生成器(TRNG)。PRNG算法基于确定性算法产生随机数序列,而TRNG算法则利用物理过程生成真正的随机数。在 Linux 或 Unix 平台上运行的Java程序默认使用的是/dev/random文件作为
熵源,如果/dev/random
在熵不足时就会阻塞。
/dev/random生成的随机数是基于环境噪声和硬件事件的熵源。它会收集在Linux操作系统中,/dev/random是一个特殊的设备文件,用于生成随机数。它是由操作系统内核提供的一个随机数生成器。/dev/random生成的随机数是基于环境噪声和硬件事件的熵源。它会收集来自硬件设备(如鼠标移动、键盘敲击、磁盘活动等)和操作系统事件(如进程调度、网络活动等)的随机性信息,并将这些信息转化为随机数。
问题已经定位到了,/dev/random
熵源不足,解决问题的思路也就有了
- 不使用
/dev/random
作为熵源 - 增加
/dev/random
熵源的数量
解决方案:
- 创建对象时直接指定策略(因为我是使用的sdk,这种没有测试,如果是自己的源码可以使用这种方式试一下,最方便)
SecureRandom secureRandom = SecureRandom.getInstance("NativePRNGNonBlocking")
- 修改jre的配置vim /jdk1.8.0_251/jre/lib/security/java.security
网上还有资料让加启动参数,我经过测试并没有用,改完上面配置文件后,才生效。下面是让指定的启动参数,如果上述配置不生效可以试一下这个启动参数securerandom.strongAlgorithms=NativePRNGNonBlocking
-Djava.security.egd=file:/dev/./urandom
- 增加熵源
安装rngd软件包
# yum install rng-tools
配置,启用并启动rngd服务
如果不存在,请创建目录/etc/systemd/system /并放置/usr/lib/systemd/system/rngd.service的副本,编辑文件并修改[Service]部分,如下所示:
[Service] ExecStart=/sbin/rngd -f -r /dev/urandom -o /dev/random
运行以下命令以启用rngd服务,使其在引导时启动:
# systemctl daemon-reload
# systemctl enable rngd.service
启动rngd服务:
# systemctl start rngd.service
显示新的熵水平
cat /proc/sys/kernel/random/entropy_avail
cat /proc/sys/kernel/random/read_wakeup_threshold