I'm a little bit confused about the usage of SecureRandom
. I need to generate n secure random numbers in a loop. Is it secure to use the same SecureRandom instance for each generation? Are there any difference between the solutions below in terms of cryptographic strength?
1) Single instance without seeding
SecureRandom sr = new SecureRandom();
for(int i = 0; i < n; ++i) sr.nextInt();
2) New instance for each generation
for(int i = 0; i < n; ++i) new SecureRandom().nextInt();
3) Single instance with seeding
SecureRandom sr = new SecureRandom()
for(int i = 0; i < n; ++i) {
byte[] seed = sr.generateSeed(32);
sr.setSeed(seed);
sr.nextInt();
}
A random has only 48 bits where as SecureRandom can have upto 128 bits. So the chances of repeating in securerandom is very small. Random uses the system clock as the seed/or to generate the seed. So they can be reproduced easily if the attacker knows the time at which the seed was generated.
Yes, it is secure, as long as nextInt() is secure (for the number of integers retrieved from the stream). According to the documentation of the Random#ints() method: A pseudorandom int value is generated as if it's the result of calling the method nextInt() .
SecureRandom in any security decisions. It produces cryptographically strong random values by using a cryptographically strong pseudo-random number generator (CSPRNG).
Constructs a secure random number generator (RNG) implementing the default random number algorithm. The SecureRandom instance is seeded with the specified seed bytes. This constructor traverses the list of registered security Providers, starting with the most preferred Provider.
Perhaps counter-intuitively the third is almost certainly the weakest, reseeding on loop iteration is a terrible idea. The second is bad, but less bad, because the SecureRandom()
includes a strong default seeding strategy. As asked, the first is almost certainly the most secure because it maximizes the entropic period. I suggest you extract it to a class level constant for that reason.
private static final Random RANDOM = new SecureRandom();
// ...
// your method,
for (int i = 0; i < n; ++i) {
int num = RANDOM.nextInt();
}
I suggest you should read this interesting article
In general, there is no need to create multiple instances of SecureRandom(), as @ElliottFrisch stated a static final
is the most appropriate solution.
However, if you will use your SecureRandom for a huge sequence of random outputs, you should periodically reseed it to not allow malicious software to determine the seed and thus predict all future outputs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With