在运行时从资源中设置默认的Java SSLContext



我的问题的基本组成部分是(上下文跟随代码片段)

  1. 以下代码是否是通过-Djavax.net.ssl.keystore设置默认Java密钥库的有效替代方案
  2. 除了更改默认密钥和信任管理器之外,此代码还会对受影响JVM中SSL的行为产生什么影响
  3. 除了在运行时从资源设置默认信任/密钥存储之外,还有更好的选择吗?

    KeyStore ks = KeyStore.getInstance("JKS");
    ks.load(testService.class.getClassLoader().getResourceAsStream("resources/.keystore"), "changeit".toCharArray());
    TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
    tmf.init(ks);
    KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
    kmf.init(ks, "changeit".toCharArray());
    SSLContext ctx = SSLContext.getInstance("TLS");
    ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
    SSLContext.setDefault(ctx); 
    

围绕这个问题的背景如下。我目前正在为具有相互证书身份验证的web服务开发CXF客户端。由于各种原因,将客户端证书和密钥添加到默认密钥库不是一个理想的选项。理想情况下,我正在寻找一种方法,将密钥库作为资源文件包含在JAR中,并根据需要在运行时将其设置为默认值。我还想避免在每个对象的基础上配置每个客户端和/或连接,并支持JaxWsDynamicClientFactory之类的东西的操作(主要是为了"完整性")。

我在互联网和SO上搜索了相关材料,发现了这些(一两个)相关问题,但提供的解决方案都不是我想要的(尽管我确实把它们作为开发上述代码的跳板)。

现在,我意识到其他解决方案也可以发挥作用,但我一直在专门寻找一种能够满足所有这些要求的解决方案。

您的代码将使用与默认密钥存储和默认信任存储相同的密钥存储(从类加载器加载)。这实际上相当于将-Djavax.net.ssl.keystore*-Djavax.net.ssl.truststore*都设置为相同的值。

如果你想这样做的话,这很好。(不过,你可能需要在加载密钥库后关闭InputStream。)

这将影响整个JVM,以及使用SSLContext.getDefault()的所有东西,尤其是依赖默认SSLSocketFactoryURLConnection等等)的所有东西。

由于这将是您的默认信任存储,因此来自主要CA的默认受信任CA证书不会在您的信任存储中,除非您还将它们显式导入到从类加载器加载的副本中。

据推测,您不会有大量新的CA(或自签名)证书可信任。将密钥库和信任库分开可能更方便,因为信任库可能对大多数客户端都是通用的,而且它通常只是一开始的一次性配置步骤。

最新更新