HttpClient使用双向认证时连接复用失效,正常的HTTP或是HTTPS请求连接复用都是生效的只有在Mutual SSL时失效,但是将服务端双向认证关闭后,连接复用又能正常生效,开起了双向认证后,每一次的请求都会去进行tcp重新握手。
这是什么情况呢,对TCP的加密通信不太了解。
```java
public static void main(String[] args) throws Exception {
System.setProperty("javax.net.debug", "ssl:handshake:verbose");
CloseableHttpClient client = createMutualSSLClient(100, 20);
System.setProperty("javax.net.debug", "ssl:handshake");
HttpGet httpPost = new HttpGet("https://192.168.66.151:7891/test1");
httpPost.setHeader("Connection","keep-alive");
CloseableHttpResponse execute = client.execute(httpPost);
System.out.println(EntityUtils.toString(execute.getEntity()));
httpPost = new HttpGet("https://192.168.66.151:7891/test1");
httpPost.setHeader("Connection","keep-alive");
execute = client.execute(httpPost);
System.out.println(EntityUtils.toString(execute.getEntity()));
httpPost = new HttpGet("https://192.168.66.151:7891/test1");
httpPost.setHeader("Connection","keep-alive");
execute = client.execute(httpPost);
System.out.println(EntityUtils.toString(execute.getEntity()));
}
private static KeyStore getKeyStore(String keyStorePath, String password, String type) throws Exception {
FileInputStream inputStream = new FileInputStream(keyStorePath);
KeyStore keyStore = KeyStore.getInstance(type);
keyStore.load(inputStream, password.toCharArray());
inputStream.close();
return keyStore;
}
public static CloseableHttpClient createMutualSSLClient(Integer maxConn, Integer maxPerRoute) throws KeyException {
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create().register("HTTPS", getSSLConnectionSocketFactory()).build();
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry);
cm.setMaxTotal(maxConn);
cm.setDefaultMaxPerRoute(maxPerRoute);
return HttpClients.custom().setSSLSocketFactory(getSSLConnectionSocketFactory()).setConnectionManager(cm).setConnectionManagerShared(true).build();
}
public static SSLConnectionSocketFactory getSSLConnectionSocketFactory() throws KeyException {
try {
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
KeyStore keyStore = getKeyStore("/Users/xxx/Desktop/ssl/client.p12", "123456", "PKCS12");
keyManagerFactory.init(keyStore, "123456".toCharArray());
KeyStore trustKeyStore = getKeyStore("/Users/xxx/Desktop/ssl/root.jks", "123456", "JKS");
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(trustKeyStore);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom());
return new SSLConnectionSocketFactory(sslContext, new String[]{"TLSv1", "TLSv1.2", "TLSv1.1"}, null, new NoopHostnameVerifier());
} catch (Exception e) {
throw new KeyException("创建双向认证客户端失败" + e.getMessage(), e);
}
}
```