在我正在处理的一个项目中,应用程序是使用类似于以下的命令启动的:
java -Djava.security.egd=file:/dev/urandom -jar app.jar
Run Code Online (Sandbox Code Playgroud)
我以前从未见过这个java.security.egd
选项。搜索了一下,好像是用来在Java应用程序中配置随机数生成的。
这样对吗?应该什么时候应用?
dba*_*tor 87
TL; 博士
如果在支持 Deterministic Random Bit Generator (DRBG) 的现代操作系统上运行Java 8,我建议使用
-Djava.security.egd=file:/dev/urandom
以避免意外阻止代码。如果不确定正在使用的操作系统,我的建议是坚持原来的建议,即:
-Djava.security.egd=file:/dev/./urandom
如果运行Java 11,我建议仅使用
-Djava.security.egd=file:/dev/./urandom
以确保:
securerandom.source=file:/dev/urandom
)请继续阅读以了解详细信息。
Java 应用程序可以并且应该使用java.security.SecureRandom类通过使用加密强伪随机数生成器 ( CSPRNG )生成加密强随机值。java.util.Random类的标准 JDK 实现不被认为是加密强的。
类 Unix 操作系统有/dev/random
一个特殊文件,它提供伪随机数访问从设备驱动程序和其他来源收集的环境噪声。但是,如果可用的熵少于请求的熵,它就会阻塞;/dev/urandom
通常从不阻塞,即使伪随机数生成器种子自启动以来没有完全用熵初始化。还有第三个特殊文件,/dev/arandom
它在启动后阻塞,直到种子被安全初始化并具有足够的熵,然后再不会阻塞。
默认情况下,JVM使用为SecureRandom类设定种子/dev/random
,因此 您的 Java 代码可能会意外阻塞。-Djava.security.egd=file:/dev/./urandom
用于启动 Java 进程的命令行调用中的选项告诉 JVM 改为使用/dev/urandom
。
额外的/./
似乎使JVM使用SHA1PRNG算法,该算法使用SHA-1作为PRNG(伪随机数生成器)的基础。它比/dev/urandom
指定时使用的 NativePRNG 算法更强。
最后,有一个神话/dev/urandom
是伪随机数生成器 PRNG/dev/random
是“真”随机数生成器。这是不正确的,这两个/dev/random
和/dev/urandom
由相同CSPRNG(密码安全伪随机数发生器)被馈送。只有它们的行为不同:/dev/random
根据某些估计,当其随机池耗尽熵时阻塞,而/dev/urandom
不会。
低熵系统呢?没那么糟糕。
事实证明,“看起来随机”是一些加密组件(例如网络服务器的临时会话密钥)的基本要求。如果您采用加密散列的输出,它与随机字符串无法区分,因此密码将接受它。这就是使用 SHA1PRNG 算法的原因,因为它使用散列函数和计数器以及种子。
应该什么时候申请?
总是,我会说。
资料来源:
https://gist.github.com/svrc/5a8accc57219b9548fe1
https://www.2uo.de/myths-about-urandom
编辑 09/2020:
我已更改此更新以反映以下测试:
现代操作系统上的 -Java 8
-Java 11,因为它是当前的长期支持 (LTS) 版本。
一条评论提到了Java 8 中SecureRandom类的行为的变化。
SHA1PRNG 和 NativePRNG 已修复,以正确遵守 java.security 文件中的 SecureRandom 种子源属性。(不再需要使用 file:///dev/urandom 和 file:/dev/./urandom 的模糊解决方法。)
上面“来源”部分中引用的测试已经指出了这一点。将Java 8 中SecureRandom/./
使用的算法从 NativePRNG 更改为 SHA1PRNG 需要额外的内容。
我同意 NativePRNG 比 SHA1PRNG 更安全,但仅限于在现代操作系统上运行时。因此,我相应地更新了我的结论并将其移至顶部。
但是,我确实有一些消息要分享。根据JEP-273,自 Java 9 以来,SecureRandom类实现了NIST 800-90Ar1 中描述的三个确定性随机位生成器 (DRBG)机制。这些机制实现了与 SHA-512 和 AES-256 一样强大的现代算法。
JDK 以前有两种SecureRandom实现:
/dev/{u}random
在 Unix 上阅读或在 Windows 上使用 CryptoAPI。最新版本的 Linux 和 Windows 已经支持 DRBG,但较旧的版本和嵌入式系统可能不支持。同时Java 11 Security Developer's Guide仍然阅读
在 Linux 和 macOS 上,如果 java.security 中的熵收集设备设置为
file:/dev/urandom
或file:/dev/random
,则 NativePRNG 优先于 SHA1PRNG。否则,首选 SHA1PRNG。
为了阐明新的 DRBG 机制如何与以前的 PRNG 一起使用,我在 macOS(达尔文)上使用 AdoptOpenJDK(构建 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
最后,/dev/urandom
即使在使用现代操作系统时,作为随机源的使用点仍然是最重要的,正如我们在这篇非常有趣的文章中所读到的:
共享
/dev/random
对于任何 Linux 容器技术都是一个挑战……
虚拟化服务器上的低熵问题加剧了因为……运行在同一主机上的 Linux 容器竞争有限的熵供应。这种类型的问题有时被称为蜂群。该/dev/random
设备是一种稀缺的共享系统资源,Linux Container 租户可能没有意识到他们正在共享。当他们都试图同时使用它时,他们实际上导致了对彼此的拒绝服务。
来源:
https :
//www.openssl.org/blog/blog/2017/08/12/random/
归档时间: |
|
查看次数: |
23541 次 |
最近记录: |