ThreadLocalRandom clinit troubles

Martin Buchholz martinrb at google.com
Sun Jun 22 17:12:02 UTC 2014


We know that loading the networking machinery is problematic.  On Linux we
would be content to hard-code a read from /dev/urandom, which is safer and
strictly more random than the existing network hardware determination, but
y'all will reject that as too system-dependent (insufficient machinery!).
Hmmmm .... maybe not .... as long as we code up a good fallback ...

I learned that SecureRandom by default on Unix uses /dev/random for "seed
bytes" and /dev/urandom for nextBytes.

Here's my proposal, that in the default case on Unix doesn't load any
machinery, and as a fallback loads the SecureRandom machinery instead of
the network machinery, while maintaining the ultra-secure behavior of the
java.util.secureRandomSeed system property:


    private static long initialSeed() {
        byte[] seedBytes = initialSeedBytes();
        long s = (long)(seedBytes[0]) & 0xffL;
        for (int i = 1; i < seedBytes.length; ++i)
            s = (s << 8) | ((long)(seedBytes[i]) & 0xffL);
        return s ^ mix64(System.currentTimeMillis()) ^
mix64(System.nanoTime());
    }

    private static byte[] initialSeedBytes() {
        String pp = java.security.AccessController.doPrivileged(
                new sun.security.action.GetPropertyAction(
                        "java.util.secureRandomSeed"));
        boolean secureRandomSeed = (pp != null &&
pp.equalsIgnoreCase("true"));
        if (secureRandomSeed)
            return java.security.SecureRandom.getSeed(8);
        final byte[] seedBytes = new byte[8];
        File seedSource = new File("/dev/urandom");
        if (seedSource.exists()) {
            try (FileInputStream stream = new FileInputStream(seedSource)) {
                if (stream.read(seedBytes) == 8)
                    return seedBytes;
            } catch (IOException ignore) { }
        }
        new java.security.SecureRandom().nextBytes(seedBytes);
        return seedBytes;
    }




On Sat, Jun 21, 2014 at 9:05 PM, Martin Buchholz <martinrb at google.com>
wrote:

> While looking at NativePRNG, I filed
>
> https://bugs.openjdk.java.net/browse/JDK-8047769
>
> SecureRandom should be more frugal with file descriptors
>
> If I run this java program on Linux
>
> public class SecureRandoms {
>     public static void main(String[] args) throws Throwable {
>         new java.security.SecureRandom();
>     }
> }
>
> it creates 6 file descriptors for /dev/random and /dev/urandom, as shown
> by:
>
> strace -q -ff -e open java SecureRandoms |& grep /dev/
> [pid 20769] open("/dev/random", O_RDONLY) = 5
> [pid 20769] open("/dev/urandom", O_RDONLY) = 6
> [pid 20769] open("/dev/random", O_RDONLY) = 7
> [pid 20769] open("/dev/random", O_RDONLY) = 8
> [pid 20769] open("/dev/urandom", O_RDONLY) = 9
> [pid 20769] open("/dev/urandom", O_RDONLY) = 10
>
> Looking at jdk/src/solaris/classes/sun/security/provider/NativePRNG.java
> it looks like 2 file descriptors are created for every variant of
> NativePRNG, whether or not they are ever used. Which is wasteful. In fact,
> you only ever need at most two file descriptors, one for /dev/random and
> one for /dev/urandom.
>
> Further, it would be nice if the file descriptors were closed when idle
> and lazily re-created. Especially /dev/random should typically be used at
> startup and never thereafter.
>
>
> On Fri, Jun 20, 2014 at 7:59 AM, Alan Bateman <Alan.Bateman at oracle.com>
> wrote:
>
>> On 20/06/2014 15:02, Peter Levart wrote:
>>
>>>
>>> And, as Martin pointed out, it seems to be used for tests that exercise
>>> particular responses from NameService API to test the behaviour of JDK
>>> classes. It would be a shame for those tests to go away.
>>>
>> We've been talking about removing it for many years because it has been
>> so troublesome. If we really need to having something for testing then I
>> don't think it needs to be general purpose, we can get right of the lookup
>> at least.
>>
>> -Alan.
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/security-dev/attachments/20140622/948fceeb/attachment-0001.html>


More information about the security-dev mailing list