充气城堡安全提供程序不会在 Java 11/12 下加载

Fun*_*her 7 java bouncycastle maven-3 maven java-11

我正在尝试做一些应该是微不足道的事情,但我面临着一个问题。

将 JavaFx 应用程序从 Java 8 迁移到 Java 11 后,充气城堡安全提供程序将不会加载(也尝试了 Java 12,结果相同)。这是我更新为使用 Java 11 兼容插件的 Maven 项目。它编译得很好,但是在运行时我在终端窗口中得到了这个:

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) 在 javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:363) 在 java.base/jdk.internal.reflect.NativeMethodAccessorImpl。 invoke0(Native Method) 在 java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 在 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) 由:java.lang.NoClassDefFoundError: org/bouncycastle/jce/provider/BouncyCastleProvider at .Launcher.main(Launcher.java:14) ... 11 引起:java.lang.ClassNotFoundException:org.bouncycastle.jce。 provider.BouncyCastleProvider 在 java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583) 在 java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178) 在 java。 base/java.lang.ClassLoader.loadClass(ClassLoader.java:521) ... 12 更多

在我的 java.security 中,我将充气城堡提供者作为第一个提供者(也尝试将其作为最后一个提供者,但结果相同)

#
# 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
Run Code Online (Sandbox Code Playgroud)

在我的代码中有以下内容(过去我测试从 java 8 升级到 9 或 10 时效果很好):

            //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");
            }
Run Code Online (Sandbox Code Playgroud)

充气城堡 jar 是 bcprov-jdk15on-1.61(充气城堡提供程序版本 1.61)和 bcpkix-jdk15on-1.61.jar。住在正确的地方。

我用来启动 JavaFx 应用程序的命令行是

java -cp lib --module-path mods --add-modules=javafx.controls,javafx.fxml,javafx.graphics,javafx.web,javafx.swing -jar .Launcher 并确保 mods 和 libs 在正确放置并可以接触到罐子。

我在 StackOverflow.com 上看到了几个与此类似的问题,但尝试了提供的解决方案,但没有解决问题。

关于为什么充气城堡提供程序不会加载以及如何解决它的任何想法?

NoD*_*und 5

我认为您应该(如果尚未完成)使用 BouncyCastle 1.66 重试:它是一个带有模块信息的多版本 JAR ,可以提供帮助。

我使用的依赖项:

<dependency> 
  <groupId>org.bouncycastle</groupId>  
  <artifactId>bcprov-jdk15on</artifactId>          
  <version>1.66</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

您可以使用 JCA 启用调试模式-Djava.security.debug=jca(请参阅安全性故障排除)。

对于我的测试,我只是添加了一个新行:

security.provider.14=org.bouncycastle.jce.provider.BouncyCastleProvider
Run Code Online (Sandbox Code Playgroud)

${JAVA_HOME}/conf/security/java.security在我的 AdoptOpenJDK 11 安装中。BouncyCastle 由 Maven 作为范围 = 编译依赖项提供。

这个简单的代码:

for (final Provider provider : Security.getProviders()) {
  System.out.println("provider: " + provider.getName());
}
Run Code Online (Sandbox Code Playgroud)

显示已BC加载。

另外,如果您需要强制 BouncyCastle 作为第一个提供者,您将需要org.bouncycastle.providermodule-info.java

顺便说一句,你的代码是错误的:它不会首先插入 BC,而是最后插入:

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

文件指出Security.insertProviderAt

在指定位置添加新提供者。该位置是在提供者中搜索所请求的算法的优先顺序。该位置是从 1 开始的,即 1 是最优选的,其次是 2,依此类推。

如果您传递 0(与调用相同)Security.addProvider(Provider),您的提供程序将位于最后(请参阅ProviderList)。