Our team is using a SecureRandom to generate a list of key pairs (the SecureRandom is passed to a KeyPairGenerator). We cannot agree on which of the following two options to use:
Create a new instance every time we need to generate a key pair
Initialize a static instance and use it for all key pairs
Which approach is generally better and why?
ADDED: My gut feeling is that the second option is more secure. But my only argument is a theoretical attack based on the assumption that the pseudorandomness is derived from the current timestamp: someone may see the creation time of the key pair, guess timestamps in the surrounding time interval, compute the possible pseudorandom sequences, and obtain the key material.
ADDED: My assumption about determinism based on a timestamp was wrong. That's the difference between Random and SecureRandom. So, it looks like the answer is: in terms of security it doesn't really matter.
Once should be enough. My experience has also been that initializing SecureRandom type generators can sometimes be slow as well (due to how randomness is achieved), so you should take that into consideration.
Unlike the
java.util.Random
class, thejava.security.SecureRandom
class must produce non-deterministic output on each call.What that means is, in case of
java.util.Random
, if you were to recreate an instance with the same seed each time you needed a new random number, you would essentially get the same result every time. However,SecureRandom
is guaranteed to NOT do that - so, creating a single instance or creating a new one each time does not affect the randomness of the random bytes it generates.So, from just normal good coding practices view point, why create too many instances when one will do?
For SecureRandom you would want to consider occasionally reseeding (using system entropy in most cases) via a call like so:
so as to give a potential attacker something less than unlimited time to discover your key.
There's some great writeups about this consideration at the Justice League blog.
Why would you want to create a new instance every time? It's not like that would be more random. I think it would be best to initialize once and use it for all pairs.
Initialize a static instance and use it for all key pairs. It won't be any more or less random.
Every
SecureRandom
generation is seeded from some entropy pool. Depending on the OS used, this might be the entropy pool maintained by the OS like/dev/random
on Linux, or might be something that the JVM cooks up. In some earlier implementations, the Sun JVM used to spawn a number of threads and use their timing data to create the seed.Creating a new
SecureRandom
on every call might cause slow down of the application since creation of the seed might be blocking. Its better to reuse the a statically created instance, but make sure to reseed it after a fixed number random bytes are extracted from it.You may want to create a wrapper over a
SecureRandom
instance which counts the number of bytes extracted innextBytes
orgenerateSeed
calls and after a number of bytes, reseeds the internalSecureRandom
instance by using system entropy pool.The wrapper approach however is not possible on Java on Linux since the
SecureRandom
instance you get from newSecureRandom()
is nothing but a wrapper on/dev/random
and every call fornextBytes
orgenerateSeed
actually drains the OS entropy pool. On Linux and Solaris, its better to use a JCE provider forSecureRandom
creation.