如何在Java中启用客户端TLS会话重用

我有一个Java客户端,可以创建到同一服务器的许多会话。 TLS协议具有缓存会话密钥的function,从而避免了对每个连接进行昂贵的PKI处理。 但我无法让它真正起作用。

openssl s_client -reconnect -state -prexit -connect localhost:1234报告服务器具有“已重用,TLSv1 / SSLv3,密码为ECDHE-RSA-AES256-SHA384”以及相同的主密钥。

数据流是二进制的,而不是HTTP封装的。

我使用的代码是(约),如下所示。 它可以工作,但没有会话重用。

initSSLContext(keyStore, "password", trustStore, "PKIX", "TLSv1"); While (true) { connect(); byte[] encode1 = { 0x42, 0, 0, 0, 0, 0, 0, 0, 0, }; outs.write(encode1); byte[] ttlbuf = new byte[10000]; int len = ins.read(ttlbuf, 0, ttlbuf.length); StringBuilder sb = new StringBuilder(); socket.close(); } private void initSSLContext(KeyStore keyStore, String keyStorePwd, KeyStore trustStore, String sslTrustManagerAlg, String sslProtocol) throws Exception { KeyManager[] keyManagers = null; if ( keyStore != null && keyStorePwd != null ) { KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); kmf.init(keyStore, keyStorePwd.toCharArray()); keyManagers = kmf.getKeyManagers(); } TrustManager[] trustManagers = null; if ( trustStore != null ) { TrustManagerFactory tmf = TrustManagerFactory.getInstance(sslTrustManagerAlg); tmf.init(trustStore); trustManagers = tmf.getTrustManagers(); } ctx = SSLContext.getInstance(sslProtocol); ctx.init(keyManagers, trustManagers, null); factory = ctx.getSocketFactory(); } private void connect() throws IOException { socket = (SSLSocket) factory.createSocket(host, port); socket.setSoTimeout(30000); // ensure first ClientHello is TLSv1 rather than SSLv2 socket.setEnabledProtocols(new String[] { "TLSv1" }); socket.setEnabledCipherSuites(DEFAULT_SSL_CIPHER_SUITES); localHost = socket.getLocalAddress().getHostAddress(); localPort = socket.getLocalPort(); ins = socket.getInputStream(); outs = socket.getOutputStream(); } 

问题是任何致命警报都会导致会话恢复。 因此,阅读一个流的结尾会导致后续的重复使用。 这里还有更多

关闭连接后重新使用Java TLS会话