Java 缓存 SSL 失败——我能以某种方式刷新这些吗

标签 java ssl

我正在尝试在单元测试中测试我的 SSL 实现,但有一个场景我不太明白。

当我连接到主机一次并失败时,即使它具有正确的证书,随后的每个连接也将失败。我假设在某个地方我必须刷新缓存。

这是我的代码,服务器和客户端都在本地运行。我对 trustStore 和 keyStore 使用一个 jks-File。无论初始错误是什么,都会发生错误,下次我总是会遇到第一个错误。

如果我不执行第一个请求,第二个请求就会起作用。

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

    //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));
    }

感谢您的帮助!

最佳答案

所以我找到了一个解决方案,我想我会分享它以防其他人在某个时候遇到这个问题。

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,完整列表应为 here

关于Java 缓存 SSL 失败——我能以某种方式刷新这些吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54671365/

相关文章:

php - apns 没有在 php 中连接

.htaccess - 从 https 中删除 www

java - 我认为 printf 和字符串连接;初学者的 future 看起来很黯淡

java - 如何通过jstack找到阻塞线程的原因?

Java SSL 套接字 Web 服务器错误证书

java - 在 Java 中读取安全 session cookie

php - 使用 php 表单 POST 函数发送通过 ssl 保护的信息

Java TCP发送第一条消息,然后无限等待

java - JSP Unix 文件列表

java - 如何在集成了 Jigsaw 的情况下为 OpenJDK 9 打补丁?