If you don’t specify a seed value when you construct a SecureRandom, one will be generated for you. This is where it gets confusing. The SecureRandom class has a static member variable, also a SecureRandom, called the seed generator. It is used to generate seed values for new SecureRandom instances. Every time you create a SecureRandom using new SecureRandom(), the seed generator is used to seed your SecureRandom instance.

So how does the seed generator get seeded? SecureRandom uses an algorithm based on the timing of threads on the system to generate some supposedly random data. It uses this data to seed the seed generator itself.

Thus, real random seed generation occurs only once, the first time you construct a SecureRandom. It has two disadvantages:

  • It takes a few seconds (5-10 seconds on my Pentium 90).

  • The thread timing algorithm is not thoroughly tested. It may have weaknesses that cryptanalysts could exploit.

As Sun says in the SecureRandom documentation,

This empty constructor automatically seeds the generator. We attempt to provide sufficient seed bytes to completely randomize the internal state of the generator (20 bytes). Note, however, that our seed generation algorithm has not been thoroughly studied or widely deployed. It relies on counting the number of times that the calling thread can yield while waiting for another thread to sleep for a specified interval.

The first time this constructor is called in a given Virtual Machine, it may take several seconds of CPU time to seed the generator, depending on the underlying hardware. Successive calls run quickly because they rely on the same (internal) pseudo-random number generator for their seed bits.

Get Java Cryptography now with O’Reilly online learning.

O’Reilly members experience live online training, plus books, videos, and digital content from 200+ publishers.