如何加速Java的TLS谈判



是我需要经常阅读/设置一些信息的私人Web服务器(支持HTTPS(。我制作了一些Java代码自动执行此操作。当我使用Chrome访问它时,第一个连接很慢(可能是5秒(,但是连续连接很快(大约1s(。使用我的Java代码,每次都很慢。我知道问题是在与我的代码的各个连接中都执行完整的TLS握手。我的问题是,Chrome会做些什么来使其快速,我该如何在代码中模拟它?以下是我的代码的一部分:

    class MyTrust implements X509TrustManager{
        public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}
        public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}
        public X509Certificate[] getAcceptedIssuers() {return null; }   
    }

在建立连接的另一类中:

    URLConnection conn = (HttpsURLConnection) url.openConnection();
    SSLContext sc = SSLContext.getInstance("TLS");
    sc.init(null, new TrustManager[] { new MyTrust() }, new java.security.SecureRandom());
    ((HttpsURLConnection) conn).setSSLSocketFactory(sc.getSocketFactory());

我正在阅读Java安全套接字扩展名(JSSE(参考指南,但发现很难理解。是有效的Sessinid还是校长?谁能给我一些提示?

您的Java代码每次都建立连接,因此每次都会执行TLS握手。

但是,如果服务器接受keep-alive连接(通过返回响应中的Connection:Keep-Alive标头(,则浏览器(例如Chrome(将尝试保持连接的活力(通过请求中添加Connection:Keep-Alive标头(,大多数服务器都可以。,浏览器将尝试在正在进行的请求上使用相同的连接,因此每次都不需要执行TLS握手。

对于Java代码,您可以将连接存储在池中,然后重复使用。您可以检查支持HTTP Connection池

的Apache HTTPComponents

从评论中编辑:

由于真正的问题是关于SSL/TLS会话不起作用的。我怀疑这是由于滥用JSSE引起的。您必须在每个连接上使用相同的SSLContext才能启用会话重复使用。此外,由于连接的某些错误操作(例如,读取流的结尾(,可以丢弃会话。这里列出了一些详细信息:如何在Java中启用客户端TLS会话重复使用

最新更新