java.security.egd 选项有什么用?

What java.security.egd option is for?

在我正在处理的一个项目中,应用程序是使用类似于这样的命令启动的:

java -Djava.security.egd=file:/dev/urandom -jar app.jar

我以前从未见过 java.security.egd 选项。搜索了一下,好像是用来在Java应用程序中配置随机数生成的。

对吗?什么时候申请?

这与linux/dev/random/dev/urandom随机数生成器的区别有关

取自此link

Java Bug 6202721 states that java.security.SecureRandom uses /dev/random rather than /dev/urandom even if /dev/urandom is specified because at the time (around 2004) /dev/urandom was not working properly. The bug has never been reversed now that /dev/urandom works quite well. Therefore, you have to fake it out by obscuring the setting by using /dev/./urandom to force the use of SHA1PRNG rather than /dev/random.

回答你的问题

When is supposed to be applied?

基于上述 link,这是 Java 版本 5 所特有的,随后是 2004 年 Linux 系统上的 /dev/urandom 问题导致的。

TL;DR

如果 运行 Java 8 在现代 OSes 上支持确定性随机位生成器 (DRBG),我建议使用
-Djava.security.egd=file:/dev/urandom 来避免代码被意外阻塞。如果不确定使用的 OS,我的建议是坚持原来的建议,即:
-Djava.security.egd=file:/dev/./urandom

如果 运行 Java 11,我建议简单地使用
-Djava.security.egd=file:/dev/./urandom 来确保:

  1. 利用最强大的 SecureRandom 可用实现 (DRBG),而不管基础平台如何
  2. 避免代码被意外阻塞(securerandom.source=file:/dev/urandom)

继续阅读以了解详细信息。


Java 应用程序可以而且应该使用 java.security.SecureRandom class 通过使用密码生成加密强 运行dom 值强大的伪 运行dom 数字生成器 (CSPRNG)。 java.util.Random class 的标准 JDK 实现不被认为具有强大的加密能力。

类 Unix 操作系统有 /dev/random 一个特殊文件,它提供伪 运行dom 数字访问从设备驱动程序和其他来源收集的环境噪音。然而,如果可用的熵比请求的少,它就会阻塞; /dev/urandom 通常从不阻塞,即使伪运行dom 数字生成器种子自启动以来未完全用熵初始化。还有一个第三个特殊文件,/dev/arandom,它在启动后阻塞,直到种子已经用足够的熵安全地初始化,然后再也不会阻塞。

默认情况下,JVM 使用 /dev/random 作为 SecureRandom class 的种子,因此 您的 Java 代码可以阻止没想到。用于启动 Java 进程的命令行调用中的选项 -Djava.security.egd=file:/dev/./urandom 告诉 JVM 改用 /dev/urandom

额外的 /./ 似乎使 JVM 使用 SHA1PRNG algorithm,它使用 SHA-1 作为 PRNG(伪随机数生成器)的基础。比指定/dev/urandom时使用的NativePRNG算法强。

最后,有一个神话说 /dev/urandom 是一个伪 运行dom 数字生成器,一个 PRNG,而 /dev/random 是一个“真” 运行dom 号码生成器。这根本不是真的,/dev/random/dev/urandom 都由同一个 CSPRNG(加密安全伪 运行dom 数字生成器)提供。只有他们的行为不同:/dev/random 根据一些估计,当它的 运行domness 池耗尽熵时,/dev/random 会阻塞,而 /dev/urandom 不会。

低熵系统呢?还不错。

事实证明,“查找 运行dom”是几个加密组件(例如网络服务器的临时会话密钥)的基本要求。如果您采用加密散列的输出,它与 运行dom 字符串无法区分,因此密码会接受它。这就是使用 SHA1PRNG 算法的原因,因为它使用散列函数和计数器以及种子。

When is supposed to be applied?

总是,我会说。

来源:
https://gist.github.com/svrc/5a8accc57219b9548fe1
https://www.2uo.de/myths-about-urandom


编辑 09/2020:
我已更改此更新以反映测试:
-Java 8 在现代 OSes
-Java 11 因为它是当前的长期支持 (LTS) 版本。

一条评论提到 SecureRandom class' 在 Java 8.

中的行为发生了变化

SHA1PRNG and NativePRNG were fixed to properly respect the SecureRandom seed source properties in the java.security file. (The obscure workaround using file:///dev/urandom and file:/dev/./urandom is no longer required.)

上面来源部分引用的测试已经指出了这一点。需要额外的 /./ 才能将 SecureRandom 在 Java 8 中使用的算法从 NativePRNG 更改为 SHA1PRNG。
我同意 NativePRNG 比 SHA1PRNG 更安全, 但仅当 运行 在现代 OSes 上。因此,我相应地更新了我的结论并将其移至顶部。

不过,我确实有一些消息想与大家分享。根据 JEP-273, since Java 9 the SecureRandom class implements the three Deterministic Random Bit Generator (DRBG) mechanisms described in NIST 800-90Ar1。这些机制实现了与 SHA-512 和 AES-256 一样强大的现代算法。

JDK 之前有两种 SecureRandom 实现:

  • 一个是平台相关的,基于本地调用或 OS 设备 例如在 Unix 上阅读 /dev/{u}random 或在 Windows。 Linux 和 Windows 的最新版本已经发布 支持 DRBG,但旧版本和嵌入式系统可能不支持
  • 另一种是纯粹的 Java 实现,它使用较旧的 基于 SHA1 的 RNG 实现,不如 批准的 DRBG 机制使用的算法。

同时 Java 11 Security Developer’s Guide 仍然显示

On Linux and macOS, if the entropy gathering device in java.security is set to file:/dev/urandom or file:/dev/random, then NativePRNG is preferred to SHA1PRNG. Otherwise, SHA1PRNG is preferred.

为了阐明新的 DRBG 机制如何与以前的 PRNG 协同工作,我 运行 在 macOS (Darwin) 上使用 AdoptOpenJDK(build 11.0.7+ 10).以下是结果:


-Djava.security.egd=file:/dev/random这等于默认选项
默认算法:NativePRNG
提供者:SecureRandom.NativePRNG算法来自:SUN

-Djava.security.egd=file:/dev/urandom
默认算法:NativePRNG
提供者:SecureRandom.NativePRNG算法来自:SUN

-Djava.security.egd=file:/dev/./urandom
默认算法:DRBG
提供者:SecureRandom.DRBG算法来自:SUN


最后,即使在使用现代 OSes 时,使用 /dev/urandom 作为 运行domness 的来源仍然是最重要的,我们可以在 this very interesting post 上阅读:

Sharing /dev/random is a challenge for any Linux container technology...
The low amount of entropy on virtualized servers problem is exacerbated because ... Linux Containers running on the same host compete for a limited supply of entropy. This type of problem is sometimes referred to as a stampeding herd. The /dev/random device is a scarce shared system resource that Linux Container tenants likely have not realised they are sharing. When they all try to use it at the same time they are effectively causing a denial of service on each other.

来源:
https://www.openssl.org/blog/blog/2017/08/12/random/

如果您使用 JDK 8 或更高版本

,则不再需要

问题已被 Java 修复,这里有一些链接

大纲

SHA1PRNG and NativePRNG were fixed to properly respect the SecureRandom seed source properties in the java.security file. (The obscure workaround using file:///dev/urandom and file:/dev/./urandom is no longer required.)

更多信息(在页面中搜索随机):

https://docs.oracle.com/javase/8/docs/technotes/guides/security/enhancements-8.html

https://www.oracle.com/technetwork/java/javase/8-whats-new-2157071.html