Found the following code in our code base:
public static final int DEFAULT_LENGTH = 16; private static SecureRandom SR; static { try { SecureRandom sd0 = new SecureRandom(); SR = new SecureRandom(sd0.generateSeed(DEFAULT_LENGTH * 2)); } catch (Exception e){} }
Here a default SecureRandom
is created, and then that is used to create a seed for another one which is the one that will be used later in the class. Is this really necessary? Is the second somehow better than the first because this is done?
When the seed is generated for the second, the number of bytes is given, is this important? Could a SecureRandom
seeded with a different amount of bytes than another potentially be better or worse? Should the number of bytes used to seed it somehow correspond to what it will be used for?
If setSeed is not called, the first call to nextBytes will force the SecureRandom object to seed itself. This self-seeding will not occur if setSeed was previously called. - javadoc
Is the self-seeding not good enough? Does it depend on what it's going to be used for?
Note: For some context, it is used in class that creates random ids for stuff stored in a database.
The setSeed(long seed) method of java. security. SecureRandom class is used to reseeds this random object, using the eight bytes contained in the given long seed. The given seed supplements, rather than replaces, the existing seed. Thus, repeated calls are guaranteed never to reduce randomness.
Many SecureRandom implementations are in the form of a pseudo-random number generator (PRNG), which means they use a deterministic algorithm to produce a pseudo-random sequence from a true random seed. Other implementations may produce true random numbers, and yet others may use a combination of both techniques.
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).
I think this is completely unneccessary, because as the Javadoc you quote clearly states: Default-constructed SecureRandom
instances seed themselves. The person who wrote this probably didn't know that.
They might also actually decrease security by forcing a fixed seed length that could be less-than-ideal for the RNG implementation.
Finally, assuming the snippet is posted unaltered, the silent exception swallowing isn't very good coding style either.
Avoid using the default algorithm which is the case when doing new SecureRandom();
Instead do:
SecureRandom.getInstance("SHA1PRNG", "SUN");
If someone changes the default algorithm (as stated by @Jules) you won't be impacted.
For android, take a look at :
On Android, we don’t recommend specifying the provider. In general, any call to the Java Cryptography Extension (JCE) APIs specifying a provider should only be done if the provider is included in the application or if the application is able to deal with a possible ProviderNotFoundException.
...
in Android N we are deprecating the implementation of the SHA1PRNG algorithm and the Crypto provider altogether
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