1

我有一个调用受证书保护的 rest api 的代码,并且该代码工作了一段时间没有问题,直到我将应用程序从 Wildfly 10 迁移到 Wildfly 16。

代码本身很简单,它创建 http 请求并设置自定义套接字工厂:`

 private SSLSocketFactory getSSLSocketFactory() {
    char[] certPassword = {}; // password hidden from you 
    try {
        final KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        final SSLContext sslContext = SSLContext.getInstance("TLS");
        final KeyStore keyStore = KeyStore.getInstance("PKCS12");
        try (FileInputStream fileInputStream = new FileInputStream(new File("cert.pk12"))) {
            keyStore.load(fileInputStream, certPassword);
        } catch (final Exception e) {
            logger.error("....", e);
        }

        this.readLoadCertificateFile(keyStore);
        kmf.init(keyStore, certPassword);
        sslContext.init(kmf.getKeyManagers(), new TrustManager[]{new AnyTrust()}, null);
        return sslContext.getSocketFactory();
    } catch (Exception e) {
        logger.error(".....", e);
    }
    throw new IllegalStateException("....");
}


  HTTPRequest req = ....
  req.setSSLSocketFactory(getSSLSocketFactory());
  tokenHttpResp = req.send();`

`

一切似乎都很好,但是当我从 WF16 中运行此代码时,它会抛出

IOException:无法加载 .p12 密钥库:C:\Cert\cert.p12;构造 MAC 时出错:java.lang.SecurityException:JCE 无法验证提供者 BC;org.bouncycastle.jcajce.provider.keystore.pkcs12.PKCS12KeyStoreSpi.engineLoad::-1 java.security.KeyStore.load in KeyStore.java::1445

我检查了充气城堡库,但我在应用程序本身中没有它......如果有人知道问题可能是什么,我将不胜感激。

或者,我希望将此套接字工厂创建移动到容器本身,看起来像是专门为此设计的 Wildfly Elytron 子系统,这是个好主意吗?

4

1 回答 1

0

回答我自己的问题。“ JCE 无法验证提供者 BC ”之类的错误消息表明 jar 文件(从中加载安全提供者)无法被 JVM 验证。jar 未签名或无法验证签名。就我而言,较新的 Wildfly 版本具有较新版本的充气城堡库,由于某种原因,Java 8 无法对其进行验证。有趣的是,Java 10 就可以了。网上有人说只有这个问题发生在Oracle的JVM中,Open JDK不存在,我没有测试过,只是觉得值得一提。

要克服问题,您需要告诉 JVM 信任安全提供程序,为此,请确保您要使用的安全提供程序/JVM 决定使用,在jre/lib/security/java.security文件中提到,它应该有一行喜欢:

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

然后将带有 Security Provider 的 Jars 复制到/jre/lib/ext文件夹中

于 2019-11-27T01:09:06.523 回答