JDK-6850614 : PKCS12 Keystore.store blocks if using NativePRNG, it doesn't follow securerandom.source
  • Type: Bug
  • Component: security-libs
  • Sub-Component: java.security
  • Affected Version: 6u13
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: linux
  • CPU: x86
  • Submitted: 2009-06-12
  • Updated: 2013-04-12
  • Resolved: 2009-06-15
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
java version "1.6.0_13"
Java(TM) SE Runtime Environment (build 1.6.0_13-b03)
Java HotSpot(TM) 64-Bit Server VM (build 11.3-b02, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Linux jb3 2.6.18-6-xen-vserver-amd64 #1 SMP Thu Dec 25 22:49:16 UTC 2008 x86_64 GNU/Linux


EXTRA RELEVANT SYSTEM CONFIGURATION :

A DESCRIPTION OF THE PROBLEM :
I found that even when java.security has specified that the jvm should use /dev/urandom in stead of /dev/random, still any PKCS#12 Keystore store operation blocks on reading data from /dev/random.

[my java.security]
securerandom.source=file:/dev/urandom

This was causing real performance problems on production systems.
Why double/tripple checked  java.security  many times to rule out the problem of lack of entropy in /dev/random on a server with no keyboard, mouse and most data in memory (low hd activity).
But surprise... no matter what you set in java.security  still it uses /dev/random.


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
[example]
The following code shows the problem:
while (true)
{
KeyStore ks= KeyStore.getInstance("PKCS12");
ks.load(null);
ByteArrayOutputStream out = new ByteArrayOutputStream();
ks.store(out, key);  // blocks !!
...
...
}

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
[expected behaviour]
Whenever java.security specified that /dev/urandom should be used, the jvm should obey that, and don't fallback to /dev/random.

ACTUAL -
The code somtimes blocks for many seconds in ks.store.

[java stacktrace when it blocks]
java.lang.Thread.State: RUNNABLE
    [junit]     at java.io.FileInputStream.readBytes(Native Method)
    [junit]     at java.io.FileInputStream.read(FileInputStream.java:199)
    [junit]     at sun.security.provider.NativePRNG$RandomIO.readFully(NativePRNG.java:185)
    [junit]     at sun.security.provider.NativePRNG$RandomIO.implGenerateSeed(NativePRNG.java:202)
    [junit]     - locked <0x00002aaadf6bdae0> (a java.lang.Object)
    [junit]     at sun.security.provider.NativePRNG$RandomIO.access$300(NativePRNG.java:108)
    [junit]     at sun.security.provider.NativePRNG.engineGenerateSeed(NativePRNG.java:102)
    [junit]     at java.security.SecureRandom.generateSeed(SecureRandom.java:495)
    [junit]     at com.sun.net.ssl.internal.pkcs12.PKCS12KeyStore.getSalt(PKCS12KeyStore.java:477)
    [junit]     at com.sun.net.ssl.internal.pkcs12.PKCS12KeyStore.getAlgorithmParameters(PKCS12KeyStore.java:490)
    [junit]     at com.sun.net.ssl.internal.pkcs12.PKCS12KeyStore.encryptContent(PKCS12KeyStore.java:1131)
    [junit]     at com.sun.net.ssl.internal.pkcs12.PKCS12KeyStore.createEncryptedData(PKCS12KeyStore.java:1049)
    [junit]     at com.sun.net.ssl.internal.pkcs12.PKCS12KeyStore.engineStore(PKCS12KeyStore.java:770)
    [junit]     - locked <0x00002aaadebad138> (a com.sun.net.ssl.internal.pkcs12.PKCS12KeyStore)
    [junit]     at java.security.KeyStore.store(KeyStore.java:1117)
    [junit]     at com.vsecure.config.PKCS12Reader.ReadPKCS12file(PKCS12Reader.java:162)
    [junit]     at com.vsecure.config.PKCS12Reader.run(PKCS12Reader.java:70)


[strace]
stracing shows that ks.store() actually hangs in a read /dev/random


REPRODUCIBILITY :
This bug can be reproduced always.

Comments
JDK-6425477 should address this problem.
2013-04-12

Correct: The PKCS12 code gets a new SecureRandom() and calls generateSeed, which goes into /dev/random if the NativePRNG is indeed the default. This will hang on system with low entropy.
2012-12-15