Oracle Java 8 x64 for Linux 和 RandomSource

2022-09-02 10:59:16

我真的认为,在各种平台上安装了大约200个或更多的tomcat之后,我已经准备好迎接任何类型的挑战,但这个挑战很棘手。

我创建了一个vanilla Ubunutu 14_04映像,并在该系统上安装了Oracle的Java 8 TGZ。此外,我在游戏中添加了一只雄猫8。然后我开始安装香草服务器。

在坚持部署tomcat附带的默认应用程序后不久,我想知道那里发生了什么,并做了一些线程转储。这个是阻止tomcat启动的糟糕的线程:

"localhost-startStop-1" #15 daemon prio=5 os_prio=0 tid=0x00007f37c8004800 nid=0x4d6 runnable [0x00007f37b38b3000]
   java.lang.Thread.State: RUNNABLE
    at java.io.FileInputStream.readBytes(Native Method)
    at java.io.FileInputStream.read(FileInputStream.java:246)
    at sun.security.provider.SeedGenerator$URLSeedGenerator.getSeedBytes(SeedGenerator.java:539)
    at sun.security.provider.SeedGenerator.generateSeed(SeedGenerator.java:144)
    at sun.security.provider.SecureRandom$SeederHolder.<clinit>(SecureRandom.java:192)
    at sun.security.provider.SecureRandom.engineNextBytes(SecureRandom.java:210)
    - locked <0x00000000f06e6ce8> (a sun.security.provider.SecureRandom)
    at java.security.SecureRandom.nextBytes(SecureRandom.java:457)
    - locked <0x00000000f06e71c0> (a java.security.SecureRandom)
    at java.security.SecureRandom.next(SecureRandom.java:480)
    at java.util.Random.nextInt(Random.java:329)
    at org.apache.catalina.util.SessionIdGeneratorBase.createSecureRandom(SessionIdGeneratorBase.java:234)

在更多的谷歌和朋友之后,我发现与JDK一起发货是我问题的根源。有趣的是,有时种子生成器在几分钟后又回来了,有时它只是挂起(耗尽熵?检查通过 )。经过更多的研究,我发现一个名为的配置变量定义了 Random 的源代码是什么。在我的情况下,或者在用于linux的oracle JDK 8安装中更好,它是.我不是Linux专家(我是Java开发人员),但我的理解是,熵可能会耗尽(无论这意味着什么),但也许这意味着在某些时候它不能产生更多的随机数)。我换了,我的雄猫一切都很好。SeedGeneratorcat /proc/sys/kernel/random/entropy_avail$JAVA_HOME$/lib/security/java.securitysecurerandom.source/dev/random/dev/random/dev/urandom

然后我检查了其他JDK安装在我的其他各种服务器上的样子,这些服务器是OpenJDK和较旧的Oracle JDK安装的疯狂混合。至少OpenJDK总是使用可能的答案,为什么我以前从未遇到过这个问题。/dev/urandom

现在来回答我的问题:当操作系统无法产生更多数字的极端情况下,Oracle是否明智地依赖它?我的意思是像Tomcat这样的服务器和许多其他服务器依赖于JDK,调试这种错误真的很先进。我花了2个小时才达到我现在的位置。/dev/randomSeedGenerator


答案 1

我认为答案依赖于WebLogic支持的这个链接:https://docs.oracle.com/cd/E13209_01/wlcp/wlss30/configwlss/jvmrand.html 他们提到“随机”更安全

以及在Oracle错误评论中(David已经提到过):http://bugs.java.com/view_bug.do?bug_id=4705093

特别是关于这部分:

由于 SHA1PRNG 是基于 MessageDigest 的 PRNG,因此,如果应用程序尚未提供种子数据,则它历来始终使用 /dev/random 进行初始种子设定。由于所有将来的值都依赖于 MessageDigest 的现有状态,因此从强初始种子开始非常重要。

改变这种行为给原来的开发人员带来了麻烦。因此,他确实创建了一个名为NativePRNG的新SecureRandom impl,它确实尊重java.security.egd值。

如果您致电:

  • Linux上的新SecureRandom()和使用默认值,它将从/dev/urandom读取而不是块。(默认情况下,在 Solaris 上,使用 PKCS11 SecureRandom,并且还调用 /dev/urandom。

  • SecureRandom.getInstance(“SHA1PRNG”)并且没有指定种子,或者新的SecureRandom(),但除了“file:/dev/urandom”之外,还指定了一个备用java.security.egd,它将使用SHA1PRNG调用/dev/random,并可能被阻止。

  • SecureRandom.getInstance(“NativePRNG”),这将取决于java.security.egd指向的内容。


答案 2

我的理解是/dev/random可以耗尽熵(无论这意味着什么),但也许这意味着在某些时候它不能生成更多的随机数)。

它可以暂时耗尽熵并阻塞,直到它聚集到足以分配更多。JVM 只需要一点点来为实例设定种子。SecureRandom

需要多长时间取决于系统的噪声程度以及内核如何收集熵。

当操作系统无法产生更多数字的极端情况下,依赖/dev/random是否明智?

在嵌入式系统或首次启动的VM中,缺乏熵可能是有问题的,这些系统带有非常确定性的映像,与真实PC相比,可以收获的熵源很少,并且没有RDRAND指令或类似指令,内核可以收集熵池初始化。

随机性不足对于密钥生成和其他加密算法可能是灾难性的,例如,DSA对熵源的质量非常敏感

所以,是的,宁愿等待而不是有一个受感染的系统是相当理智的。

引用来自挖掘你的Ps和Qs:N.Heninger等人的网络设备中广泛存在的弱密钥的检测

为了理解为什么会发生这些问题,我们手动调查了数百个易受攻击的主机,这些主机代表了最常重复的密钥以及我们获得的每个私钥(第3.2节)。几乎所有的信息都将它们标识为无外设或嵌入式系统,包括路由器,服务器管理卡,防火墙和其他网络反操作。此类设备通常在首次启动时自动生成密钥,并且可能具有与传统PC兼容的有限熵源。

此外,当我们检查共享密钥或因子的主机群集时,在几乎所有情况下,这些主机似乎都由制造商或设备型号链接。这些观察结果使我们得出结论,这些问题是由特定的缺陷实现引起的,这些实现在没有收集到足够的熵的情况下生成密钥。

如果你有一个熵和root权限的外部源,你可以把额外的熵推到池中,并增加它的计数器(我认为可以为你做到这一点)。只是写 to 会把你的熵添加到池中,但不会增加计数器。rngd/dev/random

对于 VM,还有一些虚拟化驱动程序用于从主机获取熵。

将 jvm 指向硬件 RNG 开发(/dev/hwrng、/dev/misc/hw_random 或类似的东西)也可能是一种选择,如果它们可用的话。