唐瀚林 2024-09-10 15:39 采纳率: 0%
浏览 10
已结题

HttpClient使用双向认证时连接复用失效!

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


```

  • 写回答

0条回答 默认 最新

    报告相同问题?

    问题事件

    • 系统已结题 9月18日
    • 创建了问题 9月10日