Consider the following snippet where I use AES-256 to generate keys to encrypt - the thread which runs the following snippet gets blocked. I'm suspecting whether this could be due to the problem that sufficient entropy is not reached. So, that the thread could suspend (or) looks hanging till sufficient entropy is gathered by the system.
I run this on a virtual machine and not on a physical one and I'm using Java8.
SNIPPET A
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(256);
SecretKey key = keyGen.generateKey();
The following article infers that SecureRandom
instance when obtained as
SecureRandom secureRandom = new SecureRandom();
The NativePRNG
algorithm which is used by default to generate entropy is referred as SHA1PRNG
which uses /dev/urandom
by default and hence no thread blocking could occur.
I'll come to the point why I'm speaking about these stuffs. The line
keyGen.init(256);
in the above snippet does the following action internally.
public final void init(int paramInt) {
init(paramInt, JceSecurity.RANDOM);
}
and what this JceSecurity.RANDOM
has is this
static final SecureRandom RANDOM = new SecureRandom();
Means it should have used /dev/urandom
and this shouldn't have blocked (or) hanged when the entropy is not gathered.
I'm sharing my java.security file here.
Can someone shed some insight on why the above thread which runs the SNIPPET A
blocks?
In the end a random number generator will always depend on the entropy sources of the operating system, if just for seeding; it is impossible to generate random numbers from non-random environment after all.
I can imagine that a VM with limited amount of entropy sources has trouble filling up the entry pool, if just once. The best way to resolve this issue is to make sure that your VM has the latest client additions installed. Those could / should make the hosts RNG available to the client machine.
It is possible to once create a SecureRandom
instance and pass it as parameter to the various init()
methods. However, that would not solve blocking it right at the start, and it unnecessarily complicates code. Finally, you'll never know which library or module still instantiates another SecureRandom
instance.
So I'd focus on fixing the RNG of the client VM rather than the Java code.
Note that NativePRNG
uses the OS RNG directly; it does not use "SHA1PRNG"
. The SecureRandom()
uses the first provider that contains an implementation of the class; make sure you haven't included a provider with a slow PRNG if the default PRNG is used.