Java SecureRandom doesn't block? How?
Both OpenJDK and Sun read from /dev/urandom
, not /dev/random
, at least on the machine where I tested (OpenJDK JRE 6b27 and Sun JRE 6.26 on Debian squeeze amd64). For some reason, they both open /dev/random
as well but never read from it. So the blog articles you read either were mistaken or applied to a different version from mine (and, apparently, yours).
You can check whether yours reads from /dev/random
or /dev/urandom
by tracing it:
strace -o a.strace -f -e file java A
and look for the relevant part of the trace:
21165 open("/dev/random", O_RDONLY) = 6
…
21165 open("/dev/urandom", O_RDONLY) = 7
…
21165 read(7, "\322\223\211\262Zs\300\345\3264l\254\354[\6wS\326q@", 20) = 20
…
Don't worry, /dev/urandom
is perfectly fine for cryptography.
Java's SecureRandom does use /dev/random, but only briefly.
Specifically it only uses it when generating seed information, either by explicitly calling SecureRandom.generateSeed()
or by the first call to nextInt()
So therefore, to repeat your bash example you can do the following, and it should block.
import java.security.SecureRandom;
public class A {
public static void main(String[] args) {
SecureRandom sr;
int out = 0;
for (int i = 0; i < 1<<20 ; i++) {
sr = new SecureRandom();
out ^= sr.nextInt();
}
System.out.println(out);
}
}
Not just to keep an old thread alive but some people might have missed a important part of the long story behind this... It's been about an well known infamous and persistent bug when using /dev/urandom from Java versions 1.4 to versions 1.7. See the links below :
http://bugs.java.com/view_bug.do?bug_id=6202721
http://bugs.java.com/view_bug.do?bug_id=4705093
For that I know, this has finally been addressed in Java 8 as stated by Oracle : https://docs.oracle.com/javase/8/docs/technotes/guides/security/enhancements-8.html
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.)