Software Integrity

 

Issues to be aware of when using Java’s SecureRandom

During a recent application assessment at Synopsys, a question came up regarding whether calls to SecureRandom can ever block. This led me to look into several SecureRandom implementations (four in Oracle JRE, and six in IBM JRE) in more detail, and I discovered some interesting facts. There seem to be at least three security issues related to SecureRandom. Let’s take a look at each one below.

Call Sequence

All SecureRandom implementations attempt to seed themselves if you don’t explicitly supply a seed. However, if you attempt to seed the following implementations before obtaining any output from the SecureRandom implementation, you will bypass the internal seeding mechanism of the SecureRandom implementation:

  • sun.security.provider.SecureRandom
  • com.ibm.crypto.provider.SecureRandom
  • com.ibm.crypto.provider.SHA1PRNG
  • com.ibm.crypto.provider.HASHDRBG
  • com.ibm.crypto.provider.SHA2DRBG
  • com.ibm.crypto.provider.SHA5DRBG

That is, one of the four SecureRandom implementations in the Oracle JRE and five of the six SecureRandom implementations in the IBM JRE behave this way. This may be desirable in some situations; for example, if you need to generate the same outputs multiple times, you can seed your SecureRandom implementation with the same seed each time. However, when unpredictability is required, bypassing the internal seeding mechanism of the PRNG is not a good idea.

Blocking

Some SecureRandom implementations in the Oracle JRE for *nix use /dev/random to get entropy at certain times. Since /dev/random can block if sufficient entropy is not available, your code will stop executing if you call certain SecureRandom methods at times when /dev/random does not have sufficient entropy available. The following SecureRandom implementations have this potential problem:

  • sun.security.provider.SecureRandom
  • sun.security.provider.NativePRNG

This problem can occur in the following instances:

  • Whenever sun.security.provider.NativePRNG.generateSeed() is called. This reads from /dev/random and can block.
  • Whenever sun.security.provider.SecureRandom.generateSeed() is called AND egdSource in the JRE is set to /dev/urandom or /dev/random. egdSource is set using the java.security.egd system property or the securerandom.source property in your java.security file, and is set to /dev/urandom by default.
  • The very first time a sun.security.provider.SecureRandom instance attempts to seed itself. In this case, a static instance of sun.security.provider.SecureRandom (shared among all sun.security.provider.SecureRandom instances) is created that seeds itself using /dev/random as long as egdSource is set to /dev/random or /dev/urandom.

Note that we did not discuss the deprecated getSeed() method, which behaves differently than generateSeed(). Since it’s deprecated, we will not discuss it further.

Internal Seeding Mechanism

Some SecureRandom implementations seed themselves using entropy obtained from the underlying operating system. In some cases, these can be configured to gather entropy in other ways. Other SecureRandom implementations attempt to generate entropy without relying on the underlying operating system. The following implementations generate entropy without relying on the underlying operating system:

  • sun.security.provider.SecureRandom if egdSource is NOT set to /dev/random or /dev/urandom. If egdSource points to a valid file/URL, it uses that to gather entropy; otherwise, it attempts to generate a seed itself.
  • com.ibm.crypto.provider.SecureRandom
  • com.ibm.crypto.provider.SHA1PRNG
  • com.ibm.crypto.provider.HASHDRBG
  • com.ibm.crypto.provider.SHA2DRBG
  • com.ibm.crypto.provider.SHA5DRBG

Generally, relying on the operating system to generate entropy is better because the operating system has access to more sources of unpredictable data.

There are many more interesting details about several of the implementations above. I’ll write about the particular implementations in the upcoming weeks and will provide a lot more detail.

See other posts on SecureRandom