RFR 8024253: ThreadLocal random can use SecureRandom for the initial seed
Peter Levart
peter.levart at gmail.com
Mon Sep 16 14:27:42 UTC 2013
On 09/16/2013 03:54 PM, Doug Lea wrote:
> On 09/16/2013 08:46 AM, Peter Levart wrote:
>
>> What worries me is that InetAddress.getLocalHost() involves name
>> service look-up. It depends on configuration, but on my computer, it
>> takes about
>> 5s to evaluate the hostname -> IP mapping the first time the program
>> is run.
>>
>> NetworkInterface also has one method called getHardwareAddress().
>> This might me
>> interesting too...
>
> Using NetworkInterface.getHardwareAddress() is a good idea; thanks!
> Using only one of them should suffice. And just giving up on
> SecurityException seems fine.
>
> Could you check that this performs reasonably on your
> unusually-configured machine?
I checked and it performs fast. It doesn't involve name service look-up.
>
> private static long initialSeed() {
> String pp = java.security.AccessController.doPrivileged(
> new sun.security.action.GetPropertyAction(
> "java.util.secureRandomSeed"));
> if (pp != null && pp.equalsIgnoreCase("true")) {
> byte[] seedBytes = java.security.SecureRandom.getSeed(8);
> long s = (long)(seedBytes[0]) & 0xffL;
> for (int i = 1; i < 8; ++i)
> s = (s << 8) | ((long)(seedBytes[i]) & 0xffL);
> return s;
> }
> long h = 0L;
> try {
> Enumeration<NetworkInterface> ifcs =
> NetworkInterface.getNetworkInterfaces();
> if (ifcs.hasMoreElements()) {
> byte[] bs = ifcs.nextElement().getHardwareAddress();
> if (bs != null) {
> for (int i = 0; i < 8 && i < bs.length; ++i)
> h = (h << 8) ^ bs[i];
> }
> }
> } catch (Exception ignore) {
> }
> return (mix64(h ^ System.currentTimeMillis()) ^
> mix64(System.nanoTime()));
>
>
>
But not every interface has hardware address (loopback interface for
example) and the order of returned interfaces is not defined. Also with
security manager installed (System.setSecurityManager(new
RMISecurityManager()) and no extra policy, the above code always
evaluates 'h' to 0. The following is more robust (I included only the
2nd part after SecureRandom and added some prints to see what gets
evaluated):
public static long initialSeed() {
long h = 0L;
try {
h = AccessController.doPrivileged(new
PrivilegedExceptionAction<Long>() {
@Override
public Long run() throws Exception {
long h = 0L;
Enumeration<NetworkInterface> ifcs =
NetworkInterface.getNetworkInterfaces();
while (ifcs.hasMoreElements()) {
NetworkInterface ifc = ifcs.nextElement();
System.out.println(ifc);
byte[] bs = ifc.getHardwareAddress();
System.out.println(Arrays.toString(bs));
if (bs != null) {
for (int i = 0; i < 8 && i < bs.length; ++i)
h = (h << 8) ^ bs[i];
break;
}
}
return h;
}
});
} catch (Exception ignore) {
}
return (
mix64(h ^ System.currentTimeMillis()) ^
mix64(System.nanoTime())
);
}
Regards, Peter
More information about the core-libs-dev
mailing list