The difference between those classes and the SecureRandom class lies in the algorithm used.
The Random class (and the ThreadLocalRandom class, via inheritance) implements a typical
pseudorandom algorithm. While those algorithms are quite sophisticated, they are in the end
deterministic. If the initial seed is known, it is easy to determine the exact series of numbers
the engine will generate. That means hackers are able to look at series of numbers from a
particular generator and (eventually) figure out what the next number will be. Although good
pseudorandom number generators can emit series of numbers that look really random (and
that even fit probabilistic expectations of randomness), they are not truly random.
The SecureRandom class, on the other hand, uses a system interface to obtain random data.
The way that data is generated is operating-system-specific, but in general this source
provides data based on truly random events (such as when the mouse is moved). This is
known as entropy-based randomness and is much more secure for operations that rely on
random numbers. SSL encryption is the best-known example of such an operation: the ran-
dom numbers it uses for encryption are impossible to determine with an entropy-based
source. (There are other ways to break encryption methods for data, even when a Se-
cureRandom random number generator is used in the algorithm.)
Unfortunately, computers generate a limited amount of entropy, so it can take a very long
time to get a lot of random numbers from a secure random number generator. Calls to the
nextRandom() method of the SecureRandom class will take an indeterminate amount of
time, based on how much unused entropy the system has. If no entropy is available, the call
will appear to hang, possibly as long as seconds at a time, until the required entropy is avail-
able. That makes performance timing quite difficult: the performance itself becomes random.
This is often a problem for applications that create many SSL connections or otherwise need
a lot of secure random numbers; it can take such applications a long time to perform their op-
erations. When executing performance tests on such an application, be aware that the timings
will have a very large amount of variance. There really isn't any way to deal with that vari-
ance other than to run a huge number of sample tests as discussed in Chapter 2 . The other al-
ternative is to contact your operating system vendor and see if they have additional (or bet-
ter) entropy-based sources available.
In a pinch, a third alternative to this problem is to run performance tests using the Random
class, even though the SecureRandom class will be used in production. If the performance
tests are module-level tests, that can make sense: those tests will need more random numbers
(e.g., more SSL sockets) than the production system will need during the same period of
time. But eventually, the expected load must be tested with the SecureRandom class to de-