在 Apache http5 客户端上设置 SSL 参数

Setting SSL Parameters on Apache http5 Client

我正在从 Apache httpcomponents 4 升级到版本 5 以获得 http2/http1.1 支持。我需要指定我的客户提供的密码。我假设 H2/1.1 ALPN 是 AsyncHttpClient 的默认行为。

这是我当前的 httpcomponents 4 客户端代码

    // TLS
    SSLConnectionSocketFactory sslConnectionFactory = new SSLConnectionSocketFactory(
            SSLContexts.createDefault(),
            new String[] { "TLSv1.2" },
            new String[] {"TLS_AES_128_GCM_SHA256", "TLS_AES_256_GCM_SHA384",
                    "TLS_CHACHA20_POLY1305_SHA256", "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
                    "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
                    "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
                    "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
                    "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", "TLS_RSA_WITH_AES_128_GCM_SHA256",
                    "TLS_RSA_WITH_AES_256_GCM_SHA384", "TLS_RSA_WITH_AES_128_CBC_SHA",
                    "TLS_RSA_WITH_AES_256_CBC_SHA"},
            SSLConnectionSocketFactory.getDefaultHostnameVerifier());

    // Proxy
    HttpHost proxyhost = new HttpHost(proxyAddress, proxyPort);
    HttpRoutePlanner routePlanner = new DefaultProxyRoutePlanner(proxyhost);
    CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
    credentialsProvider.setCredentials(
            new AuthScope(proxyAddress, proxyPort),
            new UsernamePasswordCredentials(proxyUsername, proxyPassword)
    );

    httpClient = HttpClients.custom()
            .setRoutePlanner(routePlanner)
            .setSSLSocketFactory(sslConnectionFactory)
            .setDefaultCredentialsProvider(credentialsProvider)
            .setRedirectStrategy(new LaxRedirectStrategy())
            .setDefaultCookieStore(cookieStore)
            .build();

除了指定 SSL 工厂外,创建异步客户端的一切似乎都大致相同。因此设置 TLS 参数似乎采取了不同的路线。我花了大约一个小时寻找示例和文档,但没有成功。一些示例显示了一个名为 TLSConfig 的 class,但我找不到关于它的任何文档。

非常感谢任何帮助。

您需要构建自定义 TlsStrategy 与项目网站 [1]

上的“自定义 SSL 上下文”示例中所示的方式几乎相同

TLSConfig 将在 5.2 版本中可用,即将推出测试版。

final TlsStrategy tlsStrategy = ClientTlsStrategyBuilder.create()
    .setTlsVersions(TLS.V_1_2)
    .setCiphers("TLS_AES_128_GCM_SHA256", "TLS_AES_256_GCM_SHA384",
            "TLS_CHACHA20_POLY1305_SHA256", "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
            "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
            "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
            "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
            "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", "TLS_RSA_WITH_AES_128_GCM_SHA256",
            "TLS_RSA_WITH_AES_256_GCM_SHA384", "TLS_RSA_WITH_AES_128_CBC_SHA",
            "TLS_RSA_WITH_AES_256_CBC_SHA")
    .build();

final PoolingAsyncClientConnectionManager cm = PoolingAsyncClientConnectionManagerBuilder.create()
    .setTlsStrategy(tlsStrategy)
    .build();
try (final CloseableHttpAsyncClient client = HttpAsyncClients.custom()
    .setConnectionManager(cm)
    .build()) {

client.start();

final HttpHost target = new HttpHost("https", "httpbin.org");
final HttpClientContext clientContext = HttpClientContext.create();

final SimpleHttpRequest request = SimpleRequestBuilder.get()
        .setHttpHost(target)
        .setPath("/")
        .build();

System.out.println("Executing request " + request);
final Future<SimpleHttpResponse> future = client.execute(
        SimpleRequestProducer.create(request),
        SimpleResponseConsumer.create(),
        clientContext,
        new FutureCallback<SimpleHttpResponse>() {

            @Override
            public void completed(final SimpleHttpResponse response) {
                System.out.println(request + "->" + new StatusLine(response));
                final SSLSession sslSession = clientContext.getSSLSession();
                if (sslSession != null) {
                    System.out.println("SSL protocol " + sslSession.getProtocol());
                    System.out.println("SSL cipher suite " + sslSession.getCipherSuite());
                }
                System.out.println(response.getBody());
            }

            @Override
            public void failed(final Exception ex) {
                System.out.println(request + "->" + ex);
            }

            @Override
            public void cancelled() {
                System.out.println(request + " cancelled");
            }

        });
future.get();

System.out.println("Shutting down");
client.close(CloseMode.GRACEFUL);

[1] https://hc.apache.org/httpcomponents-client-5.1.x/examples-async.html