什么是java.security.egd选项?


22

在我正在处理的项目中,该应用程序是使用类似于以下命令的启动的:

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

我从未见过该java.security.egd选项。进行一点搜索,似乎可以用来配置Java应用程序中的随机数生成。

这样对吗?应该什么时候使用?

Answers:


29

Java应用程序可以并且应该使用java.security.SecureRandom类通过使用加密强度高的伪随机数生成器(CSPRNG)来生成加密强度高的随机值。java.util.Random类的标准JDK实现在密码学上不强。

类似Unix的操作系统具有/dev/random特殊文件,该文件提供伪随机数,以访问从设备驱动程序和其他来源收集的环境噪声。但是,如果可用的熵少于请求的熵它将阻塞/dev/urandom即使自启动以来没有用熵完全初始化伪随机数生成器种子,通常也不会阻塞。还有一个第3个特殊文件,/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


编辑04/2020:

评论提到Java 8中SecureRandom类的行为发生了变化。

SHA1PRNG和NativePRNG已修复,以正确遵守java.security文件中的SecureRandom种子源属性。(不再需要使用file:/// dev / urandom和file:/ dev /./ urandom的变通方法。)

上面“源”部分中引用的测试已经指出了这一点。额外/./需要改变所使用的算法SecureRanom在Java中8从NativePRNG到SHA1PRNG。

但是,我确实有一些要分享的新闻。根据JEP-273,从Java 9开始,SecureRandom类实现了NIST 800-90Ar1中描述的三种确定性随机位生成器(DRBG)机制。这些机制实现了强度高达SHA-512和AES-256的现代算法。

JDK有两种SecureRandom实现:

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

同时,《Java 13安全开发人员指南》仍为

在Linux和macOS上,如果java.security中的熵收集设备设置为file:/dev/urandomfile:/dev/random,则NativePRNG优于SHA1PRNG。否则,首选SHA1PRNG。

为了阐明新的DRBG机制如何与以前的PRNG一起使用,我使用AdoptOpenJDK(内部版本13.0.2 + 8)在macOS(达尔文)上运行了一些测试。结果如下:

文件:/ dev / random
提供者的优先顺序:

SecureRandom.NativePRNG
SecureRandom.DRBG
SecureRandom.SHA1PRNG

文件:/ dev / urandom
提供者的优先顺序:

SecureRandom.NativePRNG
SecureRandom.DRBG
SecureRandom.SHA1PRNG

文件:/ dev /./ urandom
提供者的优先顺序:

SecureRandom.DRBG
SecureRandom.SHA1PRNG
SecureRandom.NativePRNG

结论:

我建议使用-Djava.security.egd=file:/dev/./urandom,以确保无论使用什么平台,都可以利用最强大的SecureRandom实现,同时避免意外阻止代码。


1
从Java 8开始,不再需要文件名中多余的./的“晦涩的解决方法”,因此您可以仅使用“ / dev / urandom”,请参见:docs.oracle.com/javase/8/docs / technotes / guides / security /…
卡马尔

感谢您更新答案(特别是有关Java 9和13的更改)。不过,据我了解,从Java 8开始,将“熵收集设备”设置为/ dev / urandom或/dev/./urandom应该会产生完全相同的结果,否则该修复程序将毫无意义。从操作系统的角度来看,它们指向相同的文件,因此不会影响Java(它在修复之前就已经发生了,但这只是一个错误,而不是预期的功能)。因此,您的语句“需要额外的/./来影响PRNG的选择。” 应该不再是真实的,因为Java 8
卡马尔

感谢@Kamal的意见。我之前的短语“ PRNG选择”还不够清楚。我对它进行了重新表述,以澄清我在谈论所使用的算法:NativePRNG或SHA1PRNG。使用/dev/urandom选择NativePRNG馈送通过/dev/urandom同时/dev/./urandom拾取SHA1PRNG起来(也通过进料/dev/urandom)使用Java 8.当从Java 9起,当DRBG优先/dev/./urandom指定源。
dbaltor

1

如果您使用的是JDK 8或更高版本,则不再需要

Java已解决此问题,这是一些链接

大纲

SHA1PRNG和NativePRNG已修复,以正确遵守java.security文件中的SecureRandom种子源属性。(不再需要使用file:/// dev / urandom和file:/ dev /./ urandom的变通方法。)

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

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


我不认为这是正确的。背景信息:tersesystems.com/blog/2015/12/17/…Java 8中的修复仅表示它们现在尊重java.security文件中的SecureRandom种子源属性。但是默认情况下,它仍然包含:securerandom.source = file:/ dev / random“晦涩的解决方法”是指文件名中的多余./,也由此处接受(并获得最多投票)的答案提及。
卡马尔

该“模糊的解决办法” 只需要在特定情况下,请参阅:bugs.java.com/bugdatabase/view_bug.do?bug_id=6202721
卡迈勒

@Kamal您发布的链接引用的是Java 6和更早版本,
Venu Madhav

正是这一点,它已在Java 8中修复。根据错误报告,在Java 1.4.2到6之间需要“晦涩的解决方法”(在文件名中添加额外的./)。在Java 7中也是如此,否则,如果您要使用非阻塞设备,那么仍然需要设置/ dev / urandom而不是/ dev / random来设置Java 8中的固定值。
卡马尔

0

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

取自此链接

Java Bug 6202721指出即使指定了/ dev / urandom,java.security.SecureRandom仍使用/ dev / random而不是/ dev / urandom,因为当时(大约在2004年)/ dev / urandom无法正常工作。由于/ dev / urandom可以很好地运行,因此该错误从未消失过。因此,您必须通过使用/dev/./urandom强制使用SHA1PRNG而不是/ dev / random来掩盖设置,从而伪造出来。

回答你的问题

应该什么时候使用?

基于上述链接,这是Java版本5所特有的,其后的原因是2004年Linux系统上的/ dev / urandom问题。


该文章中可能有一个错字,因为Java错误6202721实际上指出“如果选择/ dev / urandom会出现问题,因为/ dev / random无法正常工作。” 因此,您的结论“来自/ dev / urandom的问题”是不正确的。有关选择/ dev / urandom而不是默认值(/ dev / random)的说明,请参见接受的答案。在大多数情况下,这是个好主意。
卡马尔
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.