I know that if we declare:
SecureRandom random=new SecureRandom();
It initializes the default algorithm to generate random number is NativePRNG which reads /dev/random to generate the truly random seed. Now we have truly random seed which is 160 bit size, but i am confused what happens when we call random.nextBytes(bytes);. How it generates bytes from the seed,does it again read the /dev/random or something else.
Thanks.
N.B.: i am looking for default behavior in java 7 in linux/MAC box.
From the Java API docs:
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.
So whether nextBytes(bytes) returns true random bytes from /dev/random or whether it returns pseudo-random numbers generated from the true random seed depends. The second case means that using the initially random seed, a deterministic but seemingly random (and hence, pseudo-random) number sequence is generated by any calls to the SecureRandom.
Java 7 allows for a configurable PRNG source to be specified, but on Linux the default one is NativePRNG and on Windows SHA1PRNG. You can also specify SHA1PRNG on Linux, but the default option of NativePRNG is better. The SHA1PRNG generates PRNG bits and bytes through the use of SHA1. On Linux (and possibly other Unixes, where the mechanism is "NativePRNG"), the algorithm reads from /dev/random and /dev/urandom, so as long as there is enough entropy available through either of those. For the sake of completeness, from the Linux man page on random:
A read from the /dev/urandom device will not block waiting for more entropy. As a result, if there is not sufficient entropy in the entropy pool, the returned values are theoretically vulnerable to a cryptographic attack on the algorithms used by the driver.
Therefore, on Linux at least, your SecureRandom will have a certain amount of true random output until /dev/random blocks due to a shortage of entropy, however if you request too many random bits, they will eventually start being generated by the underlying /dev/urandom machinery, which may use SHA1 or some other cryptographic hashing algorithm in a PRNG.
It's best to create a SecureRandom without specifying any explicit seed yourself, as it will seed itself (by default via /dev/random and /dev/urandom for the NativePRNG on Linux) with a good seed. Calling nextBytes(bytes) every few minutes, even for a large amount of bytes, is not bound to be an issue in almost any circumstance. Even if you are using the NativePRNG and it resorts to getting pseudo-random bytes from /dev/urandom via something like SHA-1, the output of this will still be extremely difficult to predict.
If you are asking for gigabytes of randomness, it might be good to re-seed, either using some output from the SecureRandom itself or by providing your own seed. Note that it should be safe providing any kind of seed to setSeed(), as SecureRandom internally augments the current seed by feeding the seed you provide and the previous seed to something like SHA-1 or another cryptographic hashing algorithm. However, it is still best to create the initial SecureRandom without giving your own seed.
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