How to enable client TLS session reuse in Java

9.5k Views Asked by At

I have a Java client that may create many sessions to the same server. The TLS protocol has a facility to cache session keys and thus avoid the expensive PKI processing for each connection. But I cannot get it to actually work.

openssl s_client -reconnect -state -prexit -connect localhost:1234 Reports that the server has "Reused, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-SHA384", and same master keys.

The data stream is binary, not HTTP encapsulated.

The code that I use is (approx.) as follows. It works, but no session reuse.

    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();
 }
1

There are 1 best solutions below

0
On BEST ANSWER

The problem is that any fatal alert kills the session resumption. So reading past the end of one stream kills subsequent resuse. There is more here

Java TLS Session Reuse after closed connection