avoid creating new SecureRandom to reduce CPU usage
Profiling CPU in an application showed a cpu hotspot in SecureRandom<init>.
This points to the JCAContext class, where a new SecureRandom is created for each call to getSecureRandom when no explicit SecureRandom is set.
Example stack trace:
java.security.Provider.newInstanceUtil(Class, Class, Object) <== takes time/cpu
java.security.Provider$Service.newInstance(Object)
java.security.SecureRandom.getDefaultPRNG(boolean, byte[])
java.security.SecureRandom.<init>() <== new SecureRandom each call
com.nimbusds.jose.jca.JCAContext.getSecureRandom() JCAContext.java:108
com.nimbusds.jose.crypto.factories.DefaultJWSVerifierFactory.createJWSVerifier(JWSHeader, Key) DefaultJWSVerifierFactory.java:128
com.nimbusds.jwt.proc.DefaultJWTProcessor.process(SignedJWT, SecurityContext) DefaultJWTProcessor.java:391
com.nimbusds.jwt.proc.DefaultJWTProcessor.process(JWT, SecurityContext) DefaultJWTProcessor.java:330
com.nimbusds.jwt.proc.DefaultJWTProcessor.process(String, SecurityContext) DefaultJWTProcessor.java:321
A way around this is to inject the secure random via the DefaultJWSVerifierFactory
, like so:
final var jwsVerifierFactory = new DefaultJWSVerifierFactory();
jwsVerifierFactory.getJCAContext().setSecureRandom(new SecureRandom());
jwtProcessor.setJWSVerifierFactory(jwsVerifierFactory);
Can the com.nimbusds.jose.jca.JCAContext#getSecureRandom
method also return the same instance when no explicit SecureRandom was set? This will save some processing on each call. Or is there a specific reason not to do this and return a new SecureRandom every time?
This is running on Java 11.
Comments (5)
-
-
The SecureRandom is not technically needed in the JCA context for digital signature verification, so perhaps the class can be refactored for that.
(thinking aloud)
-
- changed status to resolved
Fixed in commit 24d0794, pushed to Maven Central as v9.1.2 Happy coding :)
-
reporter Thanks for quick release!
-
reporter - changed status to closed
- Log in to comment
This is probably the seeding of the SecureRandom instance that sucks CPU cycles (triggered on the first nextBytes call).