Java缓存SSL失败 - 我能否通过某种方式清除它们?

3

我正在尝试在单元测试中测试我的SSL实现,并且有一个场景我还不能完全理解。

当我连接到某个主机失败一次后,即使它拥有正确的证书,每次连接也都会失败。 我猜想在某个地方我必须清空缓存。

这是我的代码,服务器和客户端都在本地运行。我使用一个jks文件作为trustStore和keyStore。无论初始错误是什么,我总是会在下一次得到第一个错误。

如果我不执行第一个请求,第二个请求就可以正常工作。

如果你想知道这里的用例是什么,我们有一些本地服务器使用内部PKI的https证书,当有人配置错误的服务器或证书时,我们希望能够显然地更改它们,而不必关闭整个VM。

    //attempt a connection without certificates, will fail
    try (final InputStream stream = new URL("https://localhost:" + port).openStream()){
        System.out.println(IOUtils.toString(stream, Charset.defaultCharset()));
    } catch (IOException e){
        System.out.println("Failed to load: " + StackTraceUtil.getStackTrace(e));
    }

    //copies the jks file to a temporary location
    final File jksFile = copyJKSFile();

    //ignore host names, running locally, won't use this in production
    HttpsURLConnection.setDefaultHostnameVerifier((hostname, sslSession) -> hostname.equalsIgnoreCase("localhost"));

    //set the system properties
    System.setProperty("javax.net.ssl.keyStore", jksFile.getAbsolutePath());
    System.setProperty("javax.net.ssl.keyStorePassword", password);
    System.setProperty("javax.net.ssl.trustStore", jksFile.getAbsolutePath());
    System.setProperty("javax.net.ssl.trustStorePassword", password);

    //this should work now
    try (final InputStream stream = new URL("https://localhost:" + port).openStream()){
        System.out.println(IOUtils.toString(stream, Charset.defaultCharset()));
    } catch (IOException e){
        System.out.println("Failed to load: " + StackTraceUtil.getStackTrace(e));
    }

感谢您的帮助!
1个回答

5

我找到了一个解决方案,如果有其他人遇到这个问题,我想分享一下。

javax.net.ssl.HttpsURLConnection 使用 javax.net.ssl.SSLSocketFactory 来加载 Key 和 TrustStore,它在内部使用 javax.net.ssl.SSLContext。当您没有覆盖任何内容时,它使用默认实现来加载文件,一旦加载就无法重置。

所以我做的是不使用默认实现,而是在我知道文件会更改的情况下设置自己的 SSLContext

final SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(null, null, null);
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());

如果您想使用旧版本的TLS,完整列表应在此处查看。请注意保留HTML标记。

感谢分享,我将来可能会需要 :) - Tomasz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接