There is unnecessary resource consumption in `SecureRandom.getInstance()`.

구태진 koo.taejin at gmail.com
Fri Apr 28 06:04:37 UTC 2023


Hello, this is my first e-mail  at this mailng-list.

It is an honor for me to write an e-mail here. :)
If I misunderstood and wrote an email, please forgive me.

- reproduction code
  tested on oracle-openjdk-20.0.1 and temurin-17.0.3
```
SecureRandom.getInstance("SHA1PRNG")
```

The reason it's slow is because exception is created during this operation.
(result is ok.)

```
java.lang.NoSuchMethodException.<init>()
        at java.lang.Class.getConstructor0(Class.java:3585)
        at java.lang.Class.getConstructor(Class.java:2271)
        at
java.security.Provider$Service.newInstanceUtil(Provider.java:1896)
        at java.security.Provider$Service.newInstance(Provider.java:1861)
        at sun.security.jca.GetInstance.getInstance(GetInstance.java:236)
        at sun.security.jca.GetInstance.getInstance(GetInstance.java:164)

        at java.security.SecureRandom.getInstance(SecureRandom.java:387
```

I looked up why the exception was being created.
https://github.com/openjdk/jdk/blob/0deb648985b018653ccdaf193dc13b3cf21c088a/src/java.base/share/classes/java/security/Provider.java#L1587
// addEngine("SecureRandom", false, "java.security.SecureRandomParameters");

It looks that is specifying a constructor for SecureRandom at this point.
But SecureRandom looks it doesn't have that constructor (It looks like
SecureRandomSpi has that constructor .).

For this reason, the initial creation fails and an exception is created.
As an alternative, it seems that created using a constructor without
arguments.
```
// java.security.Provider.Service#newInstanceUtil
private Object newInstanceUtil(Class<?> ctrParamClz, Object ctorParamObj)
                throws Exception
        {
            if (ctrParamClz == null) {
                return newInstanceOf();
            } else {
                // Looking for the constructor with a params first and
fallback
                // to one without if not found. This is to support the
enhanced
                // SecureRandom where both styles of constructors are
supported.
                // Before jdk9, there was no params support (only
getInstance(alg))
                // and an impl only had the params-less constructor. Since
jdk9,
                // there is getInstance(alg,params) and an impl can contain
                // an Impl(params) constructor.
                try {
                    Constructor<?> con =
getImplClass().getConstructor(ctrParamClz);
                    return con.newInstance(ctorParamObj);
                } catch (NoSuchMethodException nsme) {
                    // For pre-jdk9 SecureRandom implementations, they only
                    // have params-less constructors which still works when
                    // the input ctorParamObj is null.
                    //
                    // For other primitives using params, ctorParamObj
should not
                    // be null and nsme is thrown, just like before.
                    if (ctorParamObj == null) {
                        try {
                            return newInstanceOf();
                        } catch (NoSuchMethodException nsme2) {
                            nsme.addSuppressed(nsme2);
                            throw nsme;
                        }
                    } else {
                        throw nsme;
                    }
                }
            }
        }
```

There are two solutions I think.

1. Create a constructor for SecureRandom.
2. Compare using getConstructors instead of getConstrctor.

Thanks for reading. :)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/core-libs-dev/attachments/20230428/b968209d/attachment.htm>


More information about the core-libs-dev mailing list