18 April 2019

Directly or indirectly every developer uses random number generation during application development by different reasons:

and many more...

In Java we have insecure: java.util.Random and secure: java.security.SecureRandom random generators. Main differences between is

As result of above, for described reasons using of SecureRandom much preferable. You may never get performance issues with it until you need for number of random numbers which can be generated per time unit. Especially on cloud environment because of poor entropy.

Simple ussage and speed comparison example:

public class RandomGenerationTest {

    private static int count = 100_000_000;

    public static void main(String... s) throws Exception {
        System.out.println("Start...");
        doGeneration(new Random());
        doGeneration(new SecureRandom());
    }

    private static void doGeneration(Random random) {
        long time = System.currentTimeMillis();
        for (int i = 0; i < count; i++) {
            random.nextInt();
        }
        time = System.currentTimeMillis() - time;
        System.out.println(String.format("Generation of %s random numbers with %s time %s ms.", count, random.getClass().getName() ,time));
    }
}
Generation of 100000000 random numbers with java.util.Random time 930 ms.
Generation of 100000000 random numbers with java.security.SecureRandom time 22036 ms.

By default SecureRandom will use random data from Linux kernel entropy pool /dev/random. So in case pool went empty - next generation can be delayed for several minutes. You also can switch to the pseudo random number generator /dev/urandom which is can be must faster (non blocking) but little bit less secure.

To make Java use /dev/urandom you need to change securerandom.source property in the file jre/lib/security/java.security

securerandom.source=file:/dev/urandom

The entropy gathering device can also be specified with the System property java.security.egd. For example:

java -Djava.security.egd=file:/dev/urandom MainClass

To check how much random data is currently available in the entropy pool, use next command:

cat /proc/sys/kernel/random/entropy_avail

Every number lower than 1.000 can be considered too low for normal operation; if you request more data than available the requesting process will block. To increase entropy of Linux environment you can use HArdware Volatile Entropy Gathering and Expansion with haveged open source implementation

apt-get install haveged

It will use additional hardware(CPU) statistic to increase entropy and as result speedup your application.