Software Integrity

 

SecureRandom implementation (sun.security.provider.NativePRNG)

My previous blog entry on SecureRandom was SecureRandom Implementation (sun.security.provider.SecureRandom – SHA1PRNG). This week, I’m going to write about another implementation – the default in Oracle JRE installations on *nix.

Instantiation

This implementation is only available on *nix. On default *nix installations of Oracle JRE, this is the default SecureRandom implementation. If it is not the default implementation, it can be instantiated using:

java.security.SecureRandom.getInstance(“NativePRNG”, “SUN”);

Initial Seeding (Default)

This implementation of SecureRandom outputs the XOR of two streams:

  • /dev/urandom, which does not require any seeding by the Java application
  • SHA1PRNG which I wrote about last time, seeded using 20 bytes of data from /dev/urandom (this seeding cannot be controlled/bypassed unlike the default SHA1PRNG seeding mechanism).

Any calls to setSeed() will result in the implementation attempting to write the given seed to /dev/random. It will also call setSeed() on its SHA1PRNG instance using the given seed – this will always happen after the SHA1PRNG is already seeded using /dev/urandom.

PRNG Output

The output of the NativePRNG is the XOR of two streams:

  • A sun.security.provider.SecureRandom (SHA1PRNG) instance seeded using /dev/urandom. Note that the self-seeding mechanism of the SHA1PRNG is bypassed. Also, this SHA1PRNG instance is shared among all instances of NativePRNG.
  • Data read from /dev/urandom.

Other Seed Generation (Default)

If generateSeed() is called, /dev/random is used to generate a seed. Note that since reads from /dev/random can block if insufficient entropy is available, the seed generation operation could hang. No configuration options are available to change this seed generation mechanism.

Note that unlike what the Javadocs at http://docs.oracle.com/javase/7/docs/api/java/security/SecureRandom.html#generateSeed(int) state, the mechanism used to generate this seed is not the same as the mechanism used to seed NativePRNG instances as described in an earlier section.

Conclusions

Although the NativePRNG uses SHA1PRNG, it overrides SHA1PRNG configuration options by explicitly seeding it using the output of /dev/urandom. The main issue to be aware of when using the NativePRNG is that calling generateSeed() could cause your code to hang.