Random
and ThreadLocalRandom
are good enough for everyday use, but they have a big problem: They are based on a linear congruential generator, an algorithm whose output can be predicted rather easily. Thus, these two classes are not suitable for cryptographic uses (such as key generation).
One can use java.security.SecureRandom
in situations where a PRNG with an output that is very hard to predict is required. Predicting the random numbers created by instances of this class is hard enough to label the class as cryptographically secure.
import java.security.SecureRandom;
import java.util.Arrays;
public class Foo {
public static void main(String[] args) {
SecureRandom rng = new SecureRandom();
byte[] randomBytes = new byte[64];
rng.nextBytes(randomBytes); // Fills randomBytes with random bytes (duh)
System.out.println(Arrays.toString(randomBytes));
}
}
Besides being cryptographically secure, SecureRandom
has a gigantic period of 2160, compared to Random
s period of 248. It has one drawback of being considerably slower than Random
and other linear PRNGs such as Mersenne Twister and Xorshift, however.
Note that SecureRandom implementation is both platform and provider dependent. The default SecureRandom
(given by SUN
provider in sun.security.provider.SecureRandom
):
/dev/random
and/or /dev/urandom
.CryptGenRandom()
in CryptoAPI.