java.security.egd 选项的用途是什么?
在我正在处理的一个项目中,应用程序使用类似于以下的命令启动:
In a project I'm working on, the application is launched using a command similar to this:
java -Djava.security.egd=file:/dev/urandom -jar app.jar
我以前从未见过 java.security.egd
选项.搜了一下,好像是用来在Java应用中配置随机数生成的.
I've never seen the java.security.egd
option before. Searching a bit, it seems to be used to configure random number generation in a Java application.
对吗?什么时候申请?
推荐答案
TL;DR
如果在支持确定性随机位生成器 (DRBG) 的现代操作系统上运行 Java 8,我建议使用
-Djava.security.egd=file:/dev/urandom
以避免代码被意外阻塞.如果不确定正在使用的操作系统,我的建议是坚持原来的建议,即:
-Djava.security.egd=file:/dev/./urandom
如果运行 Java 11,我建议简单地使用
-Djava.security.egd=file:/dev/./urandom
来确保:
If running Java 8 on modern OSes with support to Deterministic Random Bit Generator (DRBG), I'd recommend using
-Djava.security.egd=file:/dev/urandom
to avoid getting the code blocked unexpectedly. If not sure about the OS being used, my suggestion is to stick with the original recommendation, namely:
-Djava.security.egd=file:/dev/./urandom
If running Java 11, I'd recommend simply using
-Djava.security.egd=file:/dev/./urandom
to make sure of:
- 利用可用的最强大的 SecureRandom 实施 (DRBG),无论基础平台如何
- 避免代码被意外阻止 (
securerandom.source=file:/dev/urandom
)
- leveraging the strongest SecureRandom implementation available (DRBG) regardless the underpinning platform
- avoiding getting the code blocked unexpectedly (
securerandom.source=file:/dev/urandom
)
继续阅读以了解详细信息.
Read on to know the details.
Java 应用程序可以并且应该使用 java.security.SecureRandom 类通过使用加密强伪随机数生成器 (CSPRNG).java.util.Random 类的标准 JDK 实现不被认为具有加密强度.
Java applications can and should use java.security.SecureRandom class to produce cryptographically strong random values by using a cryptographically strong pseudo-random number generator (CSPRNG). The standard JDK implementations of java.util.Random class are not considered cryptographically strong.
类 Unix 操作系统具有 /dev/random
,这是一个特殊文件,它提供伪随机数,访问从设备驱动程序和其他来源收集的环境噪声.但是,如果可用的熵比请求的少,它会阻塞;/dev/urandom
通常从不阻塞,即使伪随机数生成器种子在启动后没有完全用熵初始化.还有一个第三个特殊文件,/dev/arandom
,它在启动后阻塞,直到种子被安全地初始化为足够的熵,然后再也不会阻塞.
Unix-like operating systems have /dev/random
, a special file which serves pseudo random numbers accessing environmental noise collected from device drivers and other sources. However, it blocks if there is less entropy available than requested; /dev/urandom
typically never blocks, even if the pseudorandom number generator seed was not fully initialized with entropy since boot. There still is a 3rd special file, /dev/arandom
which blocks after boot until the seed has been securely initialized with enough entropy, and then never blocks again.
默认情况下,JVM 使用 /dev/random
为 SecureRandom 类播种,因此您的 Java 代码可能会意外阻塞.用于启动 Java 进程的命令行调用中的选项 -Djava.security.egd=file:/dev/./urandom
告诉 JVM 使用 /dev/urandom
代替.
By default, the JVM seeds the SecureRandom class using /dev/random
, therefore your Java code can block unexpectedly. The option -Djava.security.egd=file:/dev/./urandom
in the command line invocation used to start the Java process tells the JVM to use /dev/urandom
instead.
额外的 /./
似乎使 JVM 使用 SHA1PRNG 算法,它使用 SHA-1 作为 PRNG(伪随机数生成器)的基础.比指定/dev/urandom
时使用的NativePRNG算法强.
The extra /./
seems to make the JVM to use the SHA1PRNG algorithm which uses SHA-1 as the foundation of the PRNG (Pseudo Random Number Generator). It is stronger than the NativePRNG algorithm used when /dev/urandom
is specified.
最后,有一个神话,/dev/urandom
是一个伪随机数生成器,一个 PRNG,而 /dev/random
是一个真"随机数生成器.这根本不是真的,/dev/random
和 /dev/urandom
都由同一个 CSPRNG(加密安全伪随机数生成器)提供.只是它们的行为不同:根据某种估计,当随机池耗尽熵时,/dev/random
会阻塞,而 /dev/urandom
不会.
Finally, there is a myth that /dev/urandom
is a pseudo random number generator, a PRNG, whilst /dev/random
is a "true" random number generator. This is simply not true, both /dev/random
and /dev/urandom
are fed by the same CSPRNG (cryptographically secure pseudorandom number generator). Only their behaviour differs: /dev/random
blocks when its randomness pool runs out of entropy according to some estimate, whilst /dev/urandom
does not.
低熵系统呢?还不错.
事实证明,看起来随机"是几个加密组件的基本要求,例如网络服务器的临时会话密钥.如果您获取加密哈希的输出,它与随机字符串无法区分,因此密码将接受它.这就是使用 SHA1PRNG 算法的原因,因为它使用哈希函数和计数器,以及种子.
It turns out that "looking random" is the basic requirement for several cryptographic components such as webserver's ephemeral session keys. And if you take the output of a cryptographic hash, it is indistinguishable from a random string so that ciphers will accept it. That's the reason of using the SHA1PRNG algorithm, as it uses a hash function and a counter, together with a seed.
什么时候申请?
我会说总是.
来源:https://gist.github.com/svrc/5a8accc57219b9548fe1
https://www.2uo.de/myths-about-urandom
编辑 09/2020:
我已更改此更新以反映测试:
-现代操作系统上的 Java 8
-Java 11,因为它是当前的长期支持 (LTS) 版本.
EDIT 09/2020:
I have changed this update to reflect the tests with:
-Java 8 on modern OSes
-Java 11 as it is the currently long-term support (LTS) version.
一条评论提到了 Java 8 中 SecureRandom 类的行为发生了变化.
A comment mentions a change on SecureRandom class' behaviour in Java 8.
已修复 SHA1PRNG 和 NativePRNG 以正确尊重 java.security 文件中的 SecureRandom 种子源属性.(不再需要使用 file:///dev/urandom 和 file:/dev/./urandom 的晦涩解决方法.)
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.)
上面来源"部分中引用的测试已经指出了这一点.需要额外的 /./
将 Java 8 中 SecureRandom 使用的算法从 NativePRNG 更改为 SHA1PRNG.
我同意 NativePRNG 比 SHA1PRNG 更安全,但仅在现代操作系统上运行时.因此,我相应地更新了我的结论并将其移至顶部.
This had already been pointed out by the tests referenced on the Sources section above. The extra /./
is required to change the algorithm used by SecureRandom in Java 8 from NativePRNG to SHA1PRNG.
I agree that NativePRNG is more secure than SHA1PRNG, but only when running on modern OSes. I have therefore updated accordingly my conclusion and moved it to the top.
不过,我确实有一些消息想分享.根据 JEP-273,从 Java 9 开始,SecureRandom 类实现确定性随机位生成器 (DRBG) 机制rel="noreferrer">NIST 800-90Ar1.这些机制实现了与 SHA-512 和 AES-256 一样强大的现代算法.
However, I do have some news that I'd like to share. As per the JEP-273, since Java 9 the SecureRandom class implements the three Deterministic Random Bit Generator (DRBG) mechanisms described in NIST 800-90Ar1. These mechanisms implement modern algorithms as strong as SHA-512 and AES-256.
JDK 之前有两种 SecureRandom 实现:
The JDK previously had two kinds of SecureRandom implementations:
- 一个是平台相关的,基于本机调用或操作系统设备例如在 Unix 上读取
/dev/{u}random
或在视窗.最新版本的 Linux 和 Windows 已经支持 DRBG,但旧版本和嵌入式系统可能不支持. - 另一种是纯 Java 实现,它使用较旧的基于 SHA1 的 RNG 实现,不如经批准的 DRBG 机制使用的算法.
- One is platform-dependent and based on native calls or OS devices
such as reading
/dev/{u}random
on Unix or using the CryptoAPI on Windows. The latest releases of Linux and Windows already support DRBG, but older releases and embedded systems might not. - The other kind is a pure Java implementation that uses an older SHA1-based RNG implementation, which is not as strong as the algorithms used by approved DRBG mechanisms.
同时 Java 11 安全开发者指南 仍然是
在 Linux 和 macOS 上,如果 java.security 中的熵收集设备设置为 file:/dev/urandom
或 file:/dev/random
,则 NativePRNG 为首选SHA1PRNG.否则,首选 SHA1PRNG.
On Linux and macOS, if the entropy gathering device in java.security is set to
file:/dev/urandom
orfile:/dev/random
, then NativePRNG is preferred to SHA1PRNG. Otherwise, SHA1PRNG is preferred.
为了阐明新的 DRBG 机制如何与之前的 PRNG 协同工作,我在 macOS (Darwin) 上使用 AdoptOpenJDK(build 11.0.7+10)进行了一些测试.结果如下:
To clarify how the new DRBG mechanisms play together with the previous PRNGs, I ran some tests on macOS (Darwin) with AdoptOpenJDK (build 11.0.7+10). Here are the results:
-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
最后,即使在使用现代操作系统时,使用 /dev/urandom
作为随机源仍然是最重要的,正如我们可以在 这篇非常有趣的帖子:
Finally, the point of using /dev/urandom
as source of randomness still remains paramount even when using modern OSes, as we can read on this very interesting post:
共享 /dev/random
对任何 Linux 容器技术都是一个挑战...
虚拟化服务器上的低熵问题加剧了,因为......在同一主机上运行的 Linux 容器竞争有限的熵供应.这种类型的问题有时被称为stamped herd./dev/random
设备是一种稀缺的共享系统资源,Linux 容器租户可能没有意识到他们正在共享.当他们都试图同时使用它时,他们实际上是在互相造成拒绝服务.
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/博客/2017/08/12/random/
相关文章