FunkSoulBrother
FunkSoulBrother

Reputation: 2167

Bouncy castle security provider doesn't load under Java 11/12

I'm trying to do something that's supposed to be trivial but there is a problem that I'm facing.

The bouncy castle security provider won't load when after migrating a JavaFx application from Java 8 to Java 11 (tried Java 12 as well, same results). It's a Maven project that I updated to use Java 11 compliant plugins. It compiles fine but when running I get this in the terminal window:

jar .Launcher java.lang.reflect.InvocationTargetException at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:567) at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:464) at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:363) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:567) at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1051) Blockquote Caused by: java.lang.NoClassDefFoundError: org/bouncycastle/jce/provider/BouncyCastleProvider at .Launcher.main(Launcher.java:14) ... 11 more Caused by: java.lang.ClassNotFoundException: org.bouncycastle.jce.provider.BouncyCastleProvider at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583) at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521) ... 12 more

In my java.security I have the bouncy castle provider as the first provider (also tried it as the last provider but the results are the same)

#
# List of providers and their preference orders (see above):
#
security.provider.1=org.bouncycastle.jce.provider.BouncyCastleProvider
security.provider.2=SUN
security.provider.3=SunRsaSign
security.provider.4=SunEC
security.provider.5=SunJSSE
security.provider.6=SunJCE
security.provider.7=SunJGSS
security.provider.8=SunSASL
security.provider.9=XMLDSig
security.provider.10=SunPCSC
security.provider.11=JdkLDAP
security.provider.10=JdkSASL
security.provider.11=Apple
security.provider.12=SunPKCS11

And in my code have the following (which worked fine when I tested upgrading from java 8 to 9 or 10 in the past):

            //Since Java 9 we set the unlimited crypto policy in code, not by applying the JCE jars.
            Security.setProperty("crypto.policy", "unlimited");
            //verify that JCE is applied

            // init the BC security provider
            if (Security.getProvider("BC") == null) {
                Security.insertProviderAt(new BouncyCastleProvider(), 0);
                logger.info("Security provider added successfully");
            }

The Bouncy castle jars are bcprov-jdk15on-1.61 (Bouncy castle provider version 1.61) and bcpkix-jdk15on-1.61.jar. The reside in the right place.

the command line I use to launch the JavaFx application is

java -cp lib --module-path mods --add-modules=javafx.controls,javafx.fxml,javafx.graphics,javafx.web,javafx.swing -jar .Launcher And ensured that the mods and libs are in the right place and accessible to the jar.

I saw several problems in StackOverflow.com that resemble this one but tried the solutions offered and they don't resolve the problem.

Any ideas as to why the Bouncy castle provider won't load and how to resolve it?

Upvotes: 8

Views: 13365

Answers (1)

NoDataFound
NoDataFound

Reputation: 11969

I think you should (if not already done) retry with BouncyCastle 1.66: it is a Multi Release JAR with a module-info which could help.

The dependency that I used:

<dependency> 
  <groupId>org.bouncycastle</groupId>  
  <artifactId>bcprov-jdk15on</artifactId>          
  <version>1.66</version>
</dependency>

You can enable debug mode for JCA using -Djava.security.debug=jca (see Troubleshooting Security).

For my test, I simply added a new line:

security.provider.14=org.bouncycastle.jce.provider.BouncyCastleProvider

In the ${JAVA_HOME}/conf/security/java.security of my AdoptOpenJDK 11 installation. The BouncyCastle was provided by Maven as scope=compile dependency.

This simple code:

for (final Provider provider : Security.getProviders()) {
  System.out.println("provider: " + provider.getName());
}

Shows me that BC is loaded.

Also, if you ever need to force BouncyCastle as first provider, you will require org.bouncycastle.provider in your module-info.java:

By the way, your code is wrong: it won't insert BC first, but last:

if (Security.getProvider("BC") == null) {
  Security.insertProviderAt(new BouncyCastleProvider(), 0);
  logger.info("Security provider added successfully");
}

The documentation state that Security.insertProviderAt:

Adds a new provider, at a specified position. The position is the preference order in which providers are searched for requested algorithms. The position is 1-based, that is, 1 is most preferred, followed by 2, and so on.

If you pass 0, which is the same as calling Security.addProvider(Provider), your provider will go at the end (see ProviderList).

Upvotes: 5

Related Questions