RFR 8066397 Remove network-related seed initialization code in ThreadLocal/SplittableRandom
paul.sandoz at oracle.com
Thu Dec 4 09:40:22 UTC 2014
I think we may be over-rotating a little on this.
There is already a mechanism to create a cryptographically strong seed by setting a system property and using SecureRandom. That has a high initialization cost, but i think under those circumstances that cost is acceptable (it may well be possible to reduce that cost but i consider that to be a separate issue).
For the default case what we need is something with low initialization cost that is *good enough* for the majority of cases e.g. documents the lower bound of cryptographic strength.
I like Doug's approach to hide this under TLR, i think that fits well with the "good enough" aspect (cross seeding can be documented as an @implNote). But I still marginally prefer a public static method as well, and SecureRandom seems an appropriate choice (although it could easily be exposed on System or Runtime).
On Dec 4, 2014, at 9:20 AM, Peter Levart <peter.levart at gmail.com> wrote:
> On 12/04/2014 12:32 AM, Martin Buchholz wrote:
>> On Wed, Dec 3, 2014 at 2:15 PM, Doug Lea <dl at cs.oswego.edu> wrote:
>>> No public API because systemSeed need only be implemented
>>> inside TLR, for its initial seed. Then the others can get their seeds
>>> using ThreadLocalRandom.current().nextLong(), unless
>>> java.util.secureRandomSeed is set (which I didn't illustrate above).
>>> In other words, across all non-secure generators, you only need
>>> one system-generated seed.
>> That's good enough for seeding other non-cryptographically secure
>> PRNGs, but if you want each caller to get a
>> cryptographically secure random number, you need to avoid correlations
>> between them that would arise when you use a non-CS PRNG to generate
>> them from a single CS seed.
> Unless java.util.Random is retrofitted to allocate new cryptographically secure seed for each new instance. In such case expression:
> new java.util.Random().nextLong()
> ...could be used to gather secure seed. Perhaps even SplittableRandom could allocate new seed from secure source for each new instance (only in public constructor - not when it is split()ed)...
> What makes those workarounds unsuitable is failure mode. Gathering secure seed is inherently coupled with possible failure which must be communicated explicitly to the consumer. But one must not be bothered with failure in situations where security is not a necessary ingredient.
> So for non-CS PRNGs, cross-seeding is a possible solution, but it's nicer for all of them to just use a common (internal) API.
> As far as public API is concerned, there already is one: SecureRandom.generateSeed(). It's as good as SystemRandom (uses same primary means) and has a nice cross-platform fallback (ThreadedSeedGenerator). It's only drawback is that it comes with all the baggage of security providers (Java and MS Crypto API on Windows). But that's ok for user code perhaps.
> So what we have here is two desires:
> - we want a resource-friendly / with as little dependencies as possible way to generate some unique seed, with implicit fall-back which need not be secure
> - we want a resource-friendly / with as little dependencies as possible way to generate secure random bytes that can be pseudo-random, but still secure, with explicit failure mode
> I'll try to address this dichotomy in the next iteration of the API.
> Regards, Peter
> P.S. Is anyone interested in generating truly random bytes?
More information about the core-libs-dev