Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Repetitive usage of Java's SecureRandom

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();
}
like image 682
ovunccetin Avatar asked Dec 24 '14 20:12

ovunccetin


People also ask

How random is SecureRandom?

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.

Is SecureRandom safe?

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() .

Is SecureRandom cryptographically secure?

SecureRandom in any security decisions. It produces cryptographically strong random values by using a cryptographically strong pseudo-random number generator (CSPRNG).

What does SecureRandom do?

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.


2 Answers

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();
}
like image 200
Elliott Frisch Avatar answered Oct 05 '22 07:10

Elliott Frisch


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.

like image 27
Kostas Chalkias Avatar answered Oct 05 '22 07:10

Kostas Chalkias