Java tutorials home  java.util.Random  Random number generators  XORShift  High quality random  Seeding generators  Entropy  SecureRandom  Random sampling  Random simulations and nextGaussian()

Sources of entropy

In our discussion of seeding a random number generator, we mentioned the need to find entropy or "genuine randomness" as the seed starting point for generating other random numbers. Some typical sources that in principle we may be able to access in software include:

  • fine-grained timings between key presses;
  • fine-grained timings and positions of mouse movements;
  • fine-grained timings between interrupts and related events (packets arriving to a network card, data arriving from a disk controller...);
  • fine-grained timings at which successive threads are scheduled on to the processor;
  • (low-order bits of) the amount of free memory;
  • details of files that are liable to change frequently, e.g. the contents of the "temp" directory;
  • CPU/system temperature monitor readings;
  • noise (e.g. the least-order bit of every 24-bit sample) from a microphone input;
  • sources of "noise" from other peripherals, e.g. a TV or radio tuner.

Now, an obvious problem with all of these sources is that (a) whether they're available, (b) how easily they can be obtained in software, and (c) how many bits of genuine randomness they give, could vary hugely from machine to machine. Some of these sources are especially useful on busy, multi-user systems. Others require specific hardware to be present and require the software to have privileges that in reality will not be available unless the user makes special dispensation.

Using SecureRandom and OS-provided entropy

In practice, the modern operating systems help us solve the problem of obtaining entropy. The OS generally "knows" where it can collect entropy from, and provides an API call or some other form of access to this entropy. In Java, the SecureRandom class acts as a wrapper to this OS-provided entropy:

  • mainstream operating systems generally provide some call for us to get entropy from some of the sources listed above: they collect entropy "as they go along" and expose it to the programmar (generally via the /dev/random device file in UNIX-like systems, and via the CryptGenRandom() API call under Windows);
  • the Java SecureRandom class effectively provides access to this OS call where available, also mixing it in with some (lower-quality) sources of entropy, such as names of files in the temp directory;
  • if your program can easily generate some extra entropy, it generally "does no harm" to mix in this extra entropy, and SecureRandom provides a means to do this;
  • then, SecureRandom can generate high-quality seeds (and indeed, high-quality random numbers in general, albeit more slowly than with some other generators).

Entropy sources on Windows and Linux

In practice, current implementations of Windows and Linux derive their entropy from the following sources:

 WindowsLinux
Software interface CryptGenRandom() API call Direct read from /dev/random
Main entropy sources
  • Time (wall-clock and since boot)
  • Performance and CPU counter data
  • Timings of context switches and other software interrupts
Timings in milliseconds and additional, sometimes limited, data from:
  • Key events (timing and key code)
  • Mouse events (movement start/end, scroll direction, button press/release)
  • Completion of I/O operations on disk/block devices
  • IRQs
Reference Writing Secure Code, Second Edition, Chapter 8 Gutterman, Pinkas & Reinman (2006), Analysis of the Linux Random Number Generator

Next...

In our discussion of seeding random number generators, we look at the SecureRandom.generateSeed() call, which provides access to the underlying OS entropy source.

On the next page, we look at the SecureRandom class for random number generation, and typical cases of when to use it.

comments powered by Disqus

Written by Neil Coffey. Copyright © Javamex UK 2013. All rights reserved.