在 Java 中获取默认系统信任库的 SSLContext(JSEE)



我一直在我的程序中使用自定义密钥库,方法是指定javax.net.ssl.keyStore,javax.net.ssl.keyStorePassword,javax.net.ssl.trustStore,javax.net.ssl.trustStorePassword。我的信任库包含自签名证书。现在我想发出一些https请求(比如 https://google.com(并使用默认的jre系统trusstore,其中包含有关不同CA的信息。要发出http请求,我使用OkHttp库。它的客户端有一个选项来指定 SslSocketFactory,但要获得它,我需要为默认的 jre 信任库初始化 SSLContext。我该怎么做?

更新:我使用的代码是

    KeyStore keyStore = KeyStore.getInstance("JKS");
    // load default jvm keystore
    keyStore.load(new FileInputStream(
            System.getProperties()
                  .getProperty("java.home") + File.separator
                + "lib" + File.separator + "security" + File.separator
                + "cacerts"), "changeit".toCharArray());
    TrustManagerFactory tmf = TrustManagerFactory.getInstance(
            TrustManagerFactory.getDefaultAlgorithm());
    tmf.init(keyStore);
    SSLContext ctx = SSLContext.getInstance("TLS");
    ctx.init(null, tmf.getTrustManagers(), new SecureRandom());

javax.net.ssl.*系统属性将影响默认SSLContext,即SSLSocketFactory.getDefault()使用的和SSLContext.getDefault()返回的,如果您尚未使用自定义上下文SSLContext.setDefault(...)

如果要保留对某些连接(不是使用这些自签名证书的连接(使用默认信任库的功能,则不应使用这些属性。相反,您应该使其他连接使用为这些自签名证书构建的SSLContext。(否则,您无法真正确定地获得默认信任存储,至少如果不使用 JRE 中的私有 API。

由于您使用的库允许您指定一个SSLSocketFactory,因此当您想要使用它时,可以从您的自定义SSLContext构建一个。(如果需要,您也可以从默认SSLContext为其他情况构建一个,尽管这通常是暗示的,如果该库在连接之间重置其设置。

通过不指定其他信任存储来使用默认信任存储。 如果省略javax.net.ssl.trustStorejavax.net.ssl.trustStorePassword参数,则将使用默认值。(作为参考,这是$JAVA_HOME/jre/lib/security/cacertschangeit(是的,真的((。

最新更新