FULL PRODUCT VERSION :
Java(TM) SE Runtime Environment (build 1.6.0_03-b05)
Java HotSpot(TM) Client VM (build 1.6.0_03-b05, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Linux xxx 2.6.18-4-686 #1 SMP Wed Apr 18 09:55:10 UTC 2007 i686 GNU/Linux
probably applies to all unix platforms
A DESCRIPTION OF THE PROBLEM :
SecureRandom (Brad Notes: SHA1PRNG) always uses "/dev/random" for seed initialization
even if we specify to use "/dev/urandom" (either by the default configuration
file "jre/lib/security/java.security" or by a "-Djava.security.egd=file:/dev/urandom"
option.
[Brad Notes: Please see 4705093 for more details about this issue as to what is read and when.]
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1) Compile the java program given below
2) Run repeatedly the command "time java Foo".
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Normally all the runs should take the same (rather small) amount of time
ACTUAL -
The first runs run very fast (as expected) because /dev/random "contains"
some already calculated random bytes.
However subsequent runs will run slower and slower, as the first
bytes of /dev/random are consumed and new ones are generated rather slow.
NOTE #1: Avoid using the keyboard or moving the mouse too much
(otherwise kernel makes random bytes available to /dev/random much
faster). Actually it is rather funny, speeding up the program by just typing
frantically on the keyboard :-)
NOTE #2: To make the program run even slower, in a separate window run
the command "od -b /dev/random" and let it run continuously (this
"consumes" the bytes from /dev/random so there are even less available
for our poor java program)
NOTE #3: You can also run
strace -f -tt java Foo.java
and you will notice that /dev/random is opened twice. The first time it is
not read. However after it is opened for the second time, the read that
follows hangs for a long period of time.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.security.*;
public class Foo {
public static void main(String[] args) throws Exception {
SecureRandom x = SecureRandom.getInstance("SHA1PRNG");
byte[] b = new byte[10];
x.nextBytes(b);
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
line 69 in jre/lib/security/java.security" is:
securerandom.source=file:/dev/urandom
and should be changed to:
securerandom.source=file:///dev/urandom
(i.e. it should be a proper URL)
Similarly if you use the "-Djava.security.egd=file:/dev/urandom" option
you should change it to "-Djava.security.egd=file:///dev/urandom"