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
I've never seen the java.security.egd
option before. Searching a bit, it seems used to configure random number generation in a Java application.
Is it right? When is supposed to be applied?
This is no longer required if you are using JDK 8 or higher
The issue has been fixed by Java and here are some links
Outline
For more info (search for random in the page):
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
This is related to the difference of linux
/dev/random
and/dev/urandom
random number generator.Taken from this link
To answer your question
Based on the above link, that is something unique to Java versions 5 and following that resulted from problems with /dev/urandom on Linux systems back in 2004.
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-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.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.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.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 the behavior when their respective pool runs out of entropy, according to some estimate, differs:/dev/random
blocks, while/dev/urandom
does not.What about entropy running low? It doesn't matter.
It turns out that “looking random” is the basic requirement for a lot of our cryptographic building blocks. And if you take the output of a cryptographic hash, it has to be 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.
Always, I'd say.
Sources:
https://gist.github.com/svrc/5a8accc57219b9548fe1
https://www.2uo.de/myths-about-urandom
EDIT 04/2020:
I have changed this update to reflect the tests with Java 11 as it is the currently long-term support (LTS) version.
A comment mentions a change on SecureRandom class' behaviour in Java 8.
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.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.
The JDK previously had two kinds of SecureRandom implementations:
/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.Meanwhile the Java 11 Security Developer’s Guide still reads
To clarify how the new DRBG mechanisms play together with the previous PRNGs, I run some tests on macOS (Darwin) with AdoptOpenJDK (build 11.0.3+7). Here are the results:
-Djava.security.egd=file:/dev/random
(This equals the default option)Default algorithm: NativePRNG
Provider: SecureRandom.NativePRNG algorithm from: SUN
-Djava.security.egd=file:/dev/urandom
Default algorithm: NativePRNG
Provider: SecureRandom.NativePRNG algorithm from: SUN
-Djava.security.egd=file:/dev/./urandom
Default algorithm: MessageDigest.SHA algorithm from: SUN Using URL seed generator reading from file:/dev/./urandom
Provider: SecureRandom.DRBG algorithm from: SUN
Conclusion:
I'd recommend keep using
-Djava.security.egd=file:/dev/./urandom
with Java 11 to make sure of: