在我正在工作的项目中,应用程序是使用类似于以下命令启动的:
java -Djava.security.egd=file:/dev/urandom -jar app.jar
我以前从未见过java.security.egd
选项。查询了一些资料,似乎它用于配置Java应用程序中的随机数生成。
这是正确的吗?它应该在什么时候被应用?
简而言之
如果在支持确定性随机比特生成器(DRBG)的现代操作系统上运行Java 8,则建议使用-Djava.security.egd=file:/dev/urandom
以避免意外阻塞代码。如果不确定正在使用的操作系统,请坚持最初的建议,即:-Djava.security.egd=file:/dev/./urandom
。如果运行Java 11,则建议简单地使用-Djava.security.egd=file:/dev/./urandom
,以确保:1.利用最强大的可用SecureRandom实现(DRBG),而不管底层平台如何;2.避免意外阻塞代码(securerandom.source=file:/dev/urandom
)。Unix类操作系统有一个特殊文件/dev/random
,它通过访问从设备驱动程序和其他源收集的环境噪声来提供伪随机数。但是,如果可用熵少于请求的熵,则会阻塞;/dev/urandom
通常不会阻塞,即使伪随机数生成器种子未完全初始化。 SecureRandom默认情况下使用/dev/random
作为种子,因此您的Java代码可能会意外阻塞。命令行调用中的选项-Djava.security.egd=file:/dev/./urandom
告诉JVM改用/dev/urandom
。最后,有一个神话,即/dev/urandom
是伪随机数生成器(PRNG),而/dev/random
是“真正”的随机数生成器。这不是真的,/dev/random
和/dev/urandom
都由相同的CSPRNG提供。只有它们的行为不同:/dev/random
根据某些估计的熵耗尽时会阻塞,而/dev/urandom
则不会阻塞。建议始终使用java.security.SecureRandom类来生成加密强度的随机值。在Java 8中,SecureRandom类的SHA1PRNG和NativePRNG已经修复,以正确地遵守java.security文件中的SecureRandom种子源属性。在Java 8中,需要使用额外的/./
来更改SecureRandom使用的算法。从Java 9开始,SecureRandom类实现了三种DRBG机制。当使用现代操作系统时,NativePRNG比SHA1PRNG更安全。建议仍然使用/dev/urandom
作为随机源。/dev/random
和/dev/urandom
随机数生成器的差异有关。如果您使用JDK 8或更高版本,则不再需要此操作。
Java已经解决了这个问题,以下是一些链接:
概述
SHA1PRNG和NativePRNG已被修复,以正确地遵守java.security文件中的SecureRandom种子源属性。(不再需要使用模糊的解决方法file:///dev/urandom和file:/dev/./urandom。)
有关更多信息(在页面中搜索random):
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
/dev/urandom
会选择由/dev/urandom
提供数据的NativePRNG,而使用/dev/./urandom
则会选择由/dev/urandom
提供数据的SHA1PRNG(在Java 8中)。从Java 9开始,当指定/dev/./urandom
源时,DRBG优先于SHA1PRNG。 - dbaltor