在 JRE 1.8 中运行时安装 CA 根证书。0_51

Install CA root certificate at runtime in JRE 1.8.0_51

我正在使用 JRE 1.8。0_51(我无法更改它),它不包括 lib/security/cacerts 中 Let's Encrypt 的根证书(它被添加到 1.8.0_141)

我需要在运行时添加证书,我找到了执行此操作的代码:

        try {
            TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("X509");
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            InputStream keyStoreStream = getClass().getClassLoader().getResourceAsStream("j51_le_ca_cert.jks");
            keyStore.load(keyStoreStream, "changeit".toCharArray());
            trustManagerFactory.init(keyStore);
            TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, trustManagers, null);
            SSLContext.setDefault(sc);

        } catch (Exception e) {
            e.printStackTrace();
        }

它运行时没有抛出任何错误,但会导致以下情况之一发生:

根据系统和环境的不同,这两个事件中的哪一个似乎是任意发生的 运行。

如何才能可靠地将证书与现有证书一起安装?

根据您的问题,您似乎有以下要求:

  1. 无法升级Java,需要保持在 v1.8.051
  2. 使用默认 jdk 信任库 (cacert)
  3. 在运行时向现有证书添加额外的受信任证书

我认为这是可能的。您可以做的是创建两个单独的 TrustManagers 并将它们组合起来,如下所述:Registering multiple keystores in JVM。您只需要从默认的 jdk 信任库 (cacert) 创建一个信任管理器,并为您自己的信任库创建一个,其中包含一个让我们加密并将其与该主题中提到的 CompositeTrustManager 合并的信任库。这个特殊的 TrustManager 可用于创建 SSLContext。

我已将代码片段提取到库中,因此如果您不介意使用其他库,可以尝试以下代码片段:

import nl.altindag.ssl.SSLFactory;

import javax.net.ssl.SSLContext;

public class App {

    public static void main(String[] args) {
        SSLFactory sslFactory = SSLFactory.builder()
                .withTrustMaterial("j51_le_ca_cert.jks", "changeit".toCharArray())
                .withDefaultTrustMaterial()
                .withSslContextAlgorithm("SSL")
                .build();

        SSLContext sslContext = sslFactory.getSslContext();
        SSLContext.setDefault(sslContext);
    }

}

您可以使用以下代码片段添加库:

<dependency>
    <groupId>io.github.hakky54</groupId>
    <artifactId>sslcontext-kickstart</artifactId>
    <version>7.0.0</version>
</dependency>

有关完整文档和示例用法,请参阅此处:GitHub - SSLContext Kickstart

我认为升级您的 JDK 更好,但有时这是不可能的,所以我希望这个替代解决方案对您有用。