Java Language Random Number Generation Generating cryptographically secure pseudorandom numbers


Example

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 Randoms 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):

  • on Unix-like systems, seeded with data from /dev/random and/or /dev/urandom.
  • on Windows, seeded with calls to CryptGenRandom() in CryptoAPI.