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: <https://mail.openjdk.org/pipermail/security-dev/attachments/20140622/948fceeb/attachment.htm>
More information about the security-dev
mailing list