JEP 123: Configurable Secure Random-Number Generation
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:
- 6425477: Better support for generation of high entropy random numbers
- 6614946: error in
jre/lib/security/java.security
configuration file - 6577564: Add notes on possible block of
SecureRandom.generateSeed()/nextBytes()
Depending on how we decide to solve these issue, it may also address:
- 6258213: Request for the inclusion of a
java.random
library
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) -
Documentation: The new mechanism will need to be documented.