Matt Brown content for you

The dangers of java.security.SecureRandom

Java offers a few ways to generate random numbers, the default being java.util.Random. java.security.SecureRandom offers a more-secure extension of java.util.Random which “provides a cryptographically strong random number generator”.

“Cryptographically strong” sounds like something everyone would want, right? Why generate weak random numbers if you can generate secure random numbers instead?

Well, there is a pretty large downside to using SecureRandom in some scenarios:

If you want a cryptographically strong random number in Java, you use SecureRandom. Unfortunately, SecureRandom can be very slow. If it uses /dev/random on Linux, it can block waiting for sufficient entropy to build up.

Well, here is how the /dev/random device file in Linux works:

In this implementation, the generator keeps an estimate of the number of bits of noise in the entropy pool. From this entropy pool random numbers are created. When read, the /dev/random device will only return random bytes within the estimated number of bits of noise in the entropy pool. /dev/random should be suitable for uses that need very high quality randomness such as one-time pad or key generation. When the entropy pool is empty, reads from /dev/random will block until additional environmental noise is gathered.

If you don’t read the descriptions carefully enough, you might miss the fact that /dev/random will block when there is not enough entropy data available. This means that in practice, it’s possible for your calls to new SecureRandom() to block for an unknown amount of time.

This is great if you truly need a very strong random number - return random data generated by the environment rather than a pseudo-random number generator, and if there is none available wait until there is some more - but is a really poor choice if you don’t need a super-secure random number and just a random-enough number will do.

It’s a bad habit to use SecureRandom everywhere by default, unless you truly want to make sure your unit tests or other code-that-doesn’t-need-to-be-that-secure randomly block for long periods of time in certain environments (hint: you probably don’t want this).

Unpredictable blocking is a very bad thing for most applications.