Summary

Enhance the API for secure random-number generation so that it can be
configured to operate within specified quality and responsiveness
constraints.

Motivation

Currently, the JDK's default implementation of the SecureRandom API can
use a mix of blocking/non-blocking system calls and/or system
characteristics along with some internal digesting to generate
cryptographically secure random number and seed values. A best effort
was made to try and balance speed with randomness quality, but this does
not work for everyone. If people try to tune the implementation
configuration, the documentation is confusing (or wrong), and ultimately
does not provide the flexiblity needed. People well versed in secure
random-number generation have been asking for a better, more flexible
solution for some time.

For those not as familiar with the implementation, the primary pain point
is not understanding why applications might hang during SecureRandom
operations, especially on Linux systems. The current default
configuration obtains seed material from the Unix pseudo-file
/dev/random, and will block if not enough data is available in the
system entropy pool. While we may not be able to solve this underlying
problem, we should make some efforts to help reduce this effect.

Ultimately, these issues can lead to the blocking of applications or the
generation of secrets with insufficient entropy, and thus must be
addressed. Over the years, several escalations have been resolved with a
not-well-documented workaround, but the underlying issue of easy
configurability still remains.

As an example of the confusion that still remains, please see the
comments section of
bug 6202721.

Description

Random data is essential to many cryptographic constructs and simulation
systems. Some system random number generators (i.e. /dev/random) can
promise very high quality random data (for things like long-term stored
keys), but must block until suitable randomness can be obtained. Other
system generators (i.e. /dev/urandom) can provide reasonable quality
randomness while not blocking, which is appropriate for shorter-lived
session keys. There are also other PRNG algorithms which can measure
system characteristics to get random data. The JDK's SecureRandom
providers use a mix of these techniques, and has really made the
implementation configuration unnecessarily complex and confusing, and it
is VERY difficult to explain to developers and customers.

There are a number of bugs which should be investigated and/or addressed:

At the present time, it is not clear how to best solve these issues. In
bug 6425477, the submitter suggested a new method for SecureRandom
called getTrueRandom. That is an option, but does not address the
configuration issues. We could also use something like a new
SecureRandom algorithm name ("TrueRandom", "NonBlockingRandom"), or
add new APIs to support algorithm characteristics or properties, e.g.,

sr = new SecureRandom( ..., SR_HIGHQUALITY|SR_NON_BLOCKING);

More details will be added to this document as the work progresses.

Testing

We should make sure that the default implementation remains similar to
currently shipping products. Also, each configuration should be tested
to make sure that the documented configuration options work as
advertised. Testing for correctness may be difficult, as it may be
impossible to tell if the data obtained truly came from the requested
source(s).

Because of filename differences, a special random file name was created
for Windows. Thus this will need to be tested on all available
platforms.

Risks and Assumptions

We must consider backwards compatibility. Some applications depend on
current implementation-specific defaults (non-blocking data, blocking
seeding), and will need to take that into consideration when making
changes.

Impact

Other JDK components: Any component which requires SecureRandom
data (e.g., KeyGenerators, protocols such as SSL/TLS and Kerberos)