Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 562
FunkSoulBrother Avatar asked Mar 31 '19 04:03

FunkSoulBrother


People also ask

What is bouncy castle used for Java?

BouncyCastle is a Java library that complements the default Java Cryptographic Extension (JCE). In this introductory article, we're going to show how to use BouncyCastle to perform cryptographic operations, such as encryption and signature.

What is BouncyCastle provider?

Bouncy Castle is a Java library that complements the default Java Cryptographic Extension (JCE), and it provides more cipher suites and algorithms than the default JCE provided by Sun. In addition to that, Bouncy Castle has lots of utilities for reading arcane formats like PEM and ASN.


1 Answers

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).

like image 78
NoDataFound Avatar answered Oct 18 '22 20:10

NoDataFound