Simple Java program 100 times slower after plugging in USB hotspot

Default implementation of SecureRandom scans network interfaces as an additional source of system entropy. In order to avoid this, you need to register a custom java.security.Provider that contains a different implementation of SecureRandomSpi.

Fortunately, JDK for Windows already has a suitable SecureRandomSpi implementation that relies on Microsoft Crypto API: sun.security.mscapi.PRNG. Though this is non-public API, the class exists in all versions of OpenJDK and Oracle JDK from 1.6 to 9, and the fallback is available anyway.

There are two ways to register MS Crypto PRNG as the default SecureRandom algorithm.

1. From within the application by calling WindowsSecureRandom.register() at the very beginning.

import java.security.Provider;
import java.security.Security;

public class WindowsSecureRandom extends Provider {
    private static final String MSCAPI = "sun.security.mscapi.PRNG";

    private WindowsSecureRandom() {
        super("WindowsSecureRandom Provider", 1.0, null);
        putService(new Service(this, "SecureRandom", "Windows-PRNG", MSCAPI, null, null));
    }

    public static void register() {
        if (System.getProperty("os.name").contains("Windows")) {
            try {
                Class.forName(MSCAPI);
                Security.insertProviderAt(new WindowsSecureRandom(), 1);
            } catch (ClassNotFoundException e) {
                // Fallback to default implementation
            }
        }
    }
}

2. By reordering provider list in %JAVA_HOME%\jre\lib\security\java.security file.

security.provider.1=sun.security.mscapi.SunMSCAPI  <<<--- make it the first provider
security.provider.2=sun.security.provider.Sun
security.provider.3=sun.security.rsa.SunRsaSign
security.provider.4=sun.security.ec.SunEC
security.provider.5=com.sun.net.ssl.internal.ssl.Provider
...

I’ve verified that with either solutions SeedGenerator and NetworkInterface classes are no longer loaded.

Leave a Comment