HttpClient: ssl handshake for each request

I use static HttpClient and it works very slowly over https. I added -Djavax.net.debug = ssl and found that handshaking starts for every https request. it seems like he cannot reuse the old session, but I cannot find the reason.

9007199254743735, setSoTimeout(0) called Allow unsafe renegotiation: false Allow legacy hello messages: true Is initial handshake: true Is secure renegotiation: false 9007199254743735, setSoTimeout(0) called %% No cached client session *** ClientHello, SSLv3 ... %% Didn't cache non-resumable client session: [Session-1, SSL_RSA_WITH_RC4_128_MD5] ... Is initial handshake: true 

BTW. before I ran into another problem on this host: "Fatal warning received: bad_record_mac", it was resolved by allowing only SSLv3

UPD1: HttpClient initialization code

  final SSLContext sslCtx; sslCtx = SSLContext.getInstance("SSL"); sslCtx.init(null, new TrustManager[]{new X509TrustManager() { @Override public void checkClientTrusted(X509Certificate[] cert, String authType) { } @Override public void checkServerTrusted(X509Certificate[] cert, String authType) { } @Override public X509Certificate[] getAcceptedIssuers() { return null; } }}, null); X509HostnameVerifier verifier = new X509HostnameVerifier() { @Override public void verify(String string, SSLSocket ssls) throws IOException { } @Override public void verify(String string, X509Certificate xc) throws SSLException { } @Override public void verify(String string, String[] strings, String[] strings1) throws SSLException { } @Override public boolean verify(String string, SSLSession ssls) { return true; } }; final SSLSocketFactory socketFactory = new SSLv3SocketFactory(sslCtx, verifier); final SchemeRegistry registry = new SchemeRegistry(); registry.register(new Scheme("https", 443, socketFactory)); final PoolingClientConnectionManager cm = new PoolingClientConnectionManager(registry); cm.setMaxTotal(100); cm.setDefaultMaxPerRoute(50); final HttpParams httpParams = new BasicHttpParams(); HttpConnectionParams.setSoTimeout(httpParams, timeout); httpClient = new DefaultHttpClient(cm, httpParams); ((DefaultHttpClient) httpClient).setKeepAliveStrategy(new ConnectionKeepAliveStrategy() { @Override public long getKeepAliveDuration(HttpResponse hr, HttpContext hc) { return 0; } }); httpClient.getParams().setParameter("http.socket.timeout", 900000); 

UPD2: modified SSLSocketFactory (Fatal alert issue issue: bad_record_mac)

  public class SSLv3SocketFactory extends SSLSocketFactory { private final javax.net.ssl.SSLSocketFactory socketfactory; public SSLv3SocketFactory(SSLContext sslContext, X509HostnameVerifier hostnameVerifier) { super(sslContext, hostnameVerifier); this.socketfactory = sslContext.getSocketFactory(); } @Override public Socket createLayeredSocket( final Socket socket, final String host, final int port, final boolean autoClose) throws IOException, UnknownHostException { SSLSocket sslSocket = (SSLSocket) this.socketfactory.createSocket( socket, host, port, autoClose); sslSocket.setEnabledProtocols(new String[]{"SSLv3"}); return sslSocket; } @Override public Socket connectSocket( final Socket socket, final InetSocketAddress remoteAddress, final InetSocketAddress localAddress, final HttpParams params) throws IOException, UnknownHostException, ConnectTimeoutException { if (socket instanceof SSLSocket) { ((SSLSocket) socket).setEnabledProtocols(new String[]{"SSLv3"});; } return super.connectSocket(socket, remoteAddress, localAddress, params); } } 

UPD3: the problem exists only for SSLv3, TLSv1 works fine

+4
source share
2 answers

HttpClient reuses persistent SSL connections with client authentication only if it can verify that they belong to the same user / security context (for obvious reasons).

Make sure you use the same HttpContext for all logically related requests. This ensures that the security principal (client certificate DN) is distributed between individual HTTP requests.

Subsequent

He set up the server, he just doesn't want the connections to be reused. Each response contains a 'Connection: close' directive, which prompts the client to close connections after receiving a response. However, it may happen that the server processes different clients differently based on the composition of the request message. Try masking the HttpClient using a different User-Agent header value and see if it matters.

+2
source

As you state in the comment that the problem occurs with only one server, obviously the problem is on this server. They set a very short SSL session timeout or turned off session renewal altogether.

There is nothing you can do from your end.

0
source

Source: https://habr.com/ru/post/1494098/


All Articles