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:
| Windows | Linux |
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.
If you enjoy this Java programming article, please share with friends and colleagues. Follow the author on Twitter for the latest news and rants.
Editorial page content written by Neil Coffey. Copyright © Javamex UK 2021. All rights reserved.