3.7. Randomness
Cryptographic algorithms and protocols require a good source of
random bits, or entropy
. Randomness is used in various ways:
- To generate data-encryption keys
- As plaintext padding and initialization vectors in encryption
algorithms, to help foil cryptanalysis
- For check bytes or cookies in protocol
exchanges, as a measure against packet spoofing attacks
Randomness is harder to achieve than you might think; in fact, even
defining randomness is difficult (or picking the right definition for
a given situation). For example, "random" numbers that
are perfectly good for statistical modeling might be terrible for
cryptography. Each of these applications requires certain properties
of its random input, such as an even distribution. Cryptography, in
particular, demands
unpredictability so an
attacker reading our data can't guess our keys.
True randomness -- in the sense of complete
unpredictability -- can't be produced by a computer program.
Any sequence of bits produced as the output of a program eventually
repeats itself. For true randomness, you have to turn to physical
processes, such as fluid turbulence or the quantum dice of
radioactive decay. Even there, you must take great care that
measurement artifacts don't introduce unwanted structure.
There are algorithms, however, that produce long sequences of
practically unpredictable output, with good statistical randomness
properties. These are good enough for many cryptographic
applications, and such algorithms are called
pseudo-random number generators, or
PRNGs. A PRNG requires a small random input, called the
seed,
so it doesn't always produce the same output. From the seed,
the PRNG produces a much larger string of acceptably random output;
essentially, it is a randomness "stretcher." So a program
using a PRNG still needs to find some good random bits, just fewer of
them, but they had better be quite unpredictable.
Since various programs require random bits, some operating systems
have built-in facilities for providing them. Some Unix variants
(including Linux and OpenBSD) have a device driver, accessed through
/dev/random and
/dev/urandom, that provides random
bits when opened and read as a file. These bits are derived by all
sorts of methods, some quite clever. Correctly filtered timing
measurements of disk accesses, for example, can represent the
fluctuations due to air turbulence around the drive heads. Another
technique is to look at the least significant bits of noise coming
from an unused microphone port. And of course, they can track
fluctuating events such as network packet arrival times, keyboard
events, interrupts, etc.
SSH implementations make use of randomness, but the process is
largely invisible to the end user. Here's what happens under
the hood. SSH1 and SSH2, for example, use a kernel-based randomness
source if it is available, along with their own sampling of (one
hopes) fluctuating system parameters, gleaned by running such
programs such as
ps or
netstat.
It uses these sources to seed its PRNG, as well as to "stir
in" more randomness every once in a while. Since it can be
expensive to gather randomness, SSH stores its pool of random bits in
a file between invocations of the program, as shown in the following
table:
|
SSH1 |
SSH2 |
Server |
/etc/ssh_random_seed |
/etc/ssh2/random_seed |
Client |
~/.ssh/random_seed |
~/.ssh2/random_seed |
These files should be kept protected, since they contain sensitive
information that can weaken SSH's security if disclosed to an
attacker, although SSH takes steps to reduce that possibility. The
seed information is always mixed with some new entropy before being
used, and only half the pool is ever saved to disk, to reduce its
predictive value if stolen.
In SSH1 and SSH2, all this happens automatically and invisibly. When
compiling OpenSSH on platform without
/dev/random, you have a choice. If you have
installed an add-on randomness source, such as the
OpenSSH-recommended "
Entropy Gathering
Daemon" (EGD,
http://www.lothar.com/tech/crypto/), you can
tell OpenSSH to use it with the switch
-- with-egd-pool. If you don't specify a pool, OpenSSH uses an internal
entropy-gathering mechanism. You can tailor which programs are run to
gather entropy and "how random" they're considered
to be, by editing the file
/etc/ssh_prng_cmds.
Also, note that OpenSSH random seed is kept in the
~/.ssh/prng_seed file, even the daemon's,
which is just the root user's seed file.
| | |
3.6. As-User Access | | 3.8. SSH and File Transfers |