Forwarding some relevant comments: Brad
Set #2 of 2: From xuelei.fan (at) oracle (dot) com: From the specification, looks like that a provider would have to support both high-quality and normal-quality mode. Otherwise, SecureRandomSpi.engineSetStrongMode() should throw exception if the provider does not support high-quality mode. It does not look intuitive to me, I think a few (many be only a very few) providers may only support normal-quality or blocking mode. From the spec of SecureRandom.getStrongSecureRandom(), my understand is that the returned value may be not configured with the request mode. I mean that if application request to use high-quality secure random, the returned value may be not a high-quality secure random because the underlying provider does not support the SecureRandomSpi.engineSetStrongMode() or only supports normal-quality mode. It's confusing. Or am I miss-understanding something? BTW, the returned value of SecureRandom.getStrongSecureRandom() may not inherit the secure properties from the original caller instance, for example, the initialized seed. I think it would be better to call setSeed again on the returned value to add additional randomness. The code may look like: SecureRandom sr = ...; sr.setSeed(...); SecureRandom newSR = sr.getStrongSecureRandom(true); newSR.setSeed(...); // looks like useless, but it is useful // because the previous seed isn't inherited. I think the quality of a secure random depends on the provider. The quality may be a attribute of a provider. Personally, I like more to use block or non-block mode. I think you may have though about to use the algorithm characteristics, as the one proposed in JEP 123 description: sr = new SecureRandom( ..., SR_HIGHQUALITY|SR_NON_BLOCKING); It looks more intuitive to me, and the API may look like: // look for providers that supports the particular mode. + SecureRandom(boolean block); + SecureRandom(byte seed, boolean block); + SecureRandom.getInstance(String algorithm, boolean block); + SecureRandom.isBlockMode(); We may not need to update getInstance(String, Provider) because block or non-block is a character of a provider (get the value by isBlockMode()). Just for your consideration, may be too later. Xuelei On 1/2/2013 5:58 PM, Brad Wetmore wrote:
Hi, Please review the API/impl for JEP 123: http://openjdk.java.net/jeps/123 http://cr.openjdk.java.net/~wetmore/6425477/webrev.00/ Oracle folks, there is also the internal CCC that needs review. The bug id is 6425477. There are several SecureRandom implementations in Oracle's JDK, and together with the "configuration" options in the java.security file, it can be very confusing for users to understand. As part of the work on JEP 123, I took a comprehensive look at the different SecureRandom implementations and how we got here. There are these implementations: PKCS11: Direct calls to the native PKCS11 library. Only enabled by default on Solaris, but available for any OS. No difference between seed/random. NativePRNG: uses /dev/random and /dev/urandom for seeds/random numbers respectively. Doesn't exist on Windows. SHA1PRNG: Available on all platforms. By default, uses a confusing mix of /dev/[u]random for internal seeding and external seed generation, along with a SHA1 MessageDigest for generating random numbers. The properties (below) control seeding, but in a confusing manner. Windows-PRNG: Direct calls to the MSCAPI library, only available for Windows. No difference between seed/random. There were two main points for this JEP: 1. Provide an API that allows applications to indicate whether they want the "strongest-possible" (possibly blocking) values, or if just regular values will do. 2. See if we can clarify the configuration model, and eliminate some of the confusion caused by the securerandom.source/java.security.egd variables. This second point has caused a lot of pain for developers/deployers/support. The "workaround" of specifying "file:/dev/./urandom" or "file:///dev/urandom" instead of "file:/dev/urandom" has to be one of the most unintuitive ever. [1] ;) The default value of the variable is changed to file:/dev/random to reflect the actual implementation we've been shipping since JDK 5, but will also install NativePRNG as more preferred over the SHA1PRNG. Otherwise, the part of the implementation stays the same, and is now better documented in the java.security file. We'll also be updating the Oracle Provider documentation to reflect the implementations, but that work will be done later. Thanks, Brad [1] https://forums.oracle.com/forums/thread.jspa?messageID=3793101