如何使用 Conscrypt 和 Apache HttpClient 5 来​​加速 TLS

Posted

技术标签:

【中文标题】如何使用 Conscrypt 和 Apache HttpClient 5 来​​加速 TLS【英文标题】:How to use Conscrypt with Apache HttpClient 5 to speed up TLS 【发布时间】:2020-05-21 11:38:31 【问题描述】:

在 Apache HttpClient 5 中使用 Conscrypt 的推荐方法是什么?

我尝试将conscrypt-openjdk-uber-2.2.1.jar jar 添加到我的类路径并将我的sslcontext 配置为SSLContexts.custom().setProvider(Conscrypt.newProvider()),但是当我使用sslcontext 测试HttpClient 时,它会抛出:

[main] INFO org.apache.hc.client5.http.impl.classic.HttpRequestRetryExec - 
Recoverable I/O exception (java.net.NoRouteToHostException) caught when processing request to 
s->https://www.wikipedia.org:443

如果我删除自定义 setProvider 行,那么它可以完美运行(通过常规 J​​SSE)。

我注意到 Conscrypt 在这里被列为依赖项:https://hc.apache.org/httpcomponents-client-5.0.x/httpclient5/dependencies.html,所以也许我需要在某处启用对 Conscrypt 的内置支持?

【问题讨论】:

【参考方案1】:

你真的不需要做任何事情。 HttpClient 自动检测并配置 Conscrypt 作为其在 Java 1.7 和 1.8 上的异步 TLS 层的提供者。

对于所有较新的 JRE,可以显式配置连接管理器以使用基于 Conscrypt 的 TLS 策略:

PoolingAsyncClientConnectionManager cm = PoolingAsyncClientConnectionManagerBuilder.create()
        .setTlsStrategy(ConscryptClientTlsStrategy.getSystemDefault())
        .build();
CloseableHttpAsyncClient client = HttpAsyncClients.custom()
        .setVersionPolicy(HttpVersionPolicy.NEGOTIATE)
        .setConnectionManager(cm)
        .build();

更新

以下代码 sn-p 适用于我的 HttpClient 5.0-beta7

final SSLContext sslcontext = SSLContexts.custom()
        .setProvider(Conscrypt.newProvider())
        .build();
final SSLConnectionSocketFactory sslSocketFactory = SSLConnectionSocketFactoryBuilder.create()
        .setSslContext(sslcontext)
        .build();
final HttpClientConnectionManager cm = PoolingHttpClientConnectionManagerBuilder.create()
        .setSSLSocketFactory(sslSocketFactory)
        .build();
try (CloseableHttpClient httpclient = HttpClients.custom()
        .setConnectionManager(cm)
        .build()) 

    final HttpGet httpget = new HttpGet("https://www.wikipedia.org/");

    System.out.println("Executing request " + httpget.getMethod() + " " + httpget.getUri());

    final HttpClientContext clientContext = HttpClientContext.create();
    try (CloseableHttpResponse response = httpclient.execute(httpget, clientContext)) 
        System.out.println("----------------------------------------");
        System.out.println(response.getCode() + " " + response.getReasonPhrase());

        final SSLSession sslSession = clientContext.getSSLSession();
        if (sslSession != null) 
            System.out.println("SSL protocol " + sslSession.getProtocol());
            System.out.println("SSL cipher suite " + sslSession.getCipherSuite());
        
    

控制台输出:

Executing request GET https://www.wikipedia.org/
2020-02-06 10:33:22,619 DEBUG ex-00000001: preparing request execution
2020-02-06 10:33:22,625 DEBUG Cookie spec selected: strict
2020-02-06 10:33:22,629 DEBUG Auth cache not set in the context
2020-02-06 10:33:22,629 DEBUG ex-00000001: target auth state: UNCHALLENGED
2020-02-06 10:33:22,630 DEBUG ex-00000001: proxy auth state: UNCHALLENGED
2020-02-06 10:33:22,630 DEBUG ex-00000001: acquiring connection with route s->https://www.wikipedia.org:443
2020-02-06 10:33:22,630 DEBUG ex-00000001: acquiring endpoint (3 MINUTES)
2020-02-06 10:33:22,632 DEBUG ex-00000001: endpoint lease request (3 MINUTES) [route: s->https://www.wikipedia.org:443][total available: 0; route allocated: 0 of 5; total allocated: 0 of 25]
2020-02-06 10:33:22,636 DEBUG ex-00000001: endpoint leased [route: s->https://www.wikipedia.org:443][total available: 0; route allocated: 1 of 5; total allocated: 1 of 25]
2020-02-06 10:33:22,649 DEBUG ex-00000001: acquired ep-00000000
2020-02-06 10:33:22,649 DEBUG ex-00000001: acquired endpoint ep-00000000
2020-02-06 10:33:22,649 DEBUG ex-00000001: opening connection s->https://www.wikipedia.org:443
2020-02-06 10:33:22,650 DEBUG ep-00000000: connecting endpoint (3 MINUTES)
2020-02-06 10:33:22,650 DEBUG ep-00000000: connecting endpoint to https://www.wikipedia.org:443 (3 MINUTES)
2020-02-06 10:33:22,654 DEBUG http-outgoing-0: connecting to www.wikipedia.org/91.198.174.192:443
2020-02-06 10:33:22,654 DEBUG Connecting socket to www.wikipedia.org/91.198.174.192:443 with timeout 3 MINUTES
2020-02-06 10:33:22,759 DEBUG Enabled protocols: [TLSv1.2, TLSv1.3]
2020-02-06 10:33:22,759 DEBUG Enabled cipher suites:[TLS_AES_128_GCM_SHA256, TLS_AES_256_GCM_SHA384, TLS_CHACHA20_POLY1305_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 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, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
2020-02-06 10:33:22,759 DEBUG Starting handshake
2020-02-06 10:33:23,192 DEBUG Secure session established
2020-02-06 10:33:23,192 DEBUG  negotiated protocol: TLSv1.2
2020-02-06 10:33:23,192 DEBUG  negotiated cipher suite: TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
2020-02-06 10:33:23,192 DEBUG  peer principal: CN=*.wikipedia.org, O="Wikimedia Foundation, Inc.", L=San Francisco, ST=California, C=US
2020-02-06 10:33:23,193 DEBUG  peer alternative names: [*.wikipedia.org, *.wikimedia.org, *.wmfusercontent.org, *.wikimediafoundation.org, *.wiktionary.org, *.wikivoyage.org, *.wikiversity.org, *.wikisource.org, *.wikiquote.org, *.wikinews.org, *.wikidata.org, *.wikibooks.org, wikimedia.org, *.mediawiki.org, wikipedia.org, wikiquote.org, mediawiki.org, wmfusercontent.org, w.wiki, wikimediafoundation.org, wikibooks.org, wiktionary.org, wikivoyage.org, wikidata.org, wikiversity.org, wikisource.org, wikinews.org, *.m.wikipedia.org, *.m.wiktionary.org, *.m.wikivoyage.org, *.m.wikiquote.org, *.m.wikiversity.org, *.m.wikisource.org, *.m.wikimedia.org, *.m.wikinews.org, *.m.wikidata.org, *.m.wikibooks.org, *.planet.wikimedia.org, *.m.mediawiki.org]
2020-02-06 10:33:23,193 DEBUG  issuer principal: CN=DigiCert SHA2 High Assurance Server CA, OU=www.digicert.com, O=DigiCert Inc, C=US
2020-02-06 10:33:23,196 DEBUG http-outgoing-0: connection established 192.168.43.143:55022<->91.198.174.192:443
2020-02-06 10:33:23,196 DEBUG ep-00000000: connected http-outgoing-0
2020-02-06 10:33:23,196 DEBUG ep-00000000: endpoint connected
2020-02-06 10:33:23,197 DEBUG ex-00000001: executing GET / HTTP/1.1
2020-02-06 10:33:23,197 DEBUG ep-00000000: start execution ex-00000001
2020-02-06 10:33:23,197 DEBUG ep-00000000: executing exchange ex-00000001 over http-outgoing-0
2020-02-06 10:33:23,198 DEBUG http-outgoing-0 >> GET / HTTP/1.1
2020-02-06 10:33:23,198 DEBUG http-outgoing-0 >> Accept-Encoding: gzip, x-gzip, deflate
2020-02-06 10:33:23,198 DEBUG http-outgoing-0 >> Host: www.wikipedia.org
2020-02-06 10:33:23,198 DEBUG http-outgoing-0 >> Connection: keep-alive
2020-02-06 10:33:23,198 DEBUG http-outgoing-0 >> User-Agent: Apache-HttpClient/5.0-beta8-SNAPSHOT (Java/1.8.0_181)
2020-02-06 10:33:23,402 DEBUG http-outgoing-0 << HTTP/1.1 200 OK
2020-02-06 10:33:23,403 DEBUG http-outgoing-0 << Date: Wed, 05 Feb 2020 20:39:26 GMT
2020-02-06 10:33:23,403 DEBUG http-outgoing-0 << Cache-Control: s-maxage=86400, must-revalidate, max-age=3600
2020-02-06 10:33:23,403 DEBUG http-outgoing-0 << Server: ATS/8.0.5
2020-02-06 10:33:23,404 DEBUG http-outgoing-0 << X-ATS-Timestamp: 1580935166
2020-02-06 10:33:23,404 DEBUG http-outgoing-0 << ETag: W/"12be8-59c0633ed3519"
2020-02-06 10:33:23,404 DEBUG http-outgoing-0 << Content-Type: text/html
2020-02-06 10:33:23,404 DEBUG http-outgoing-0 << Last-Modified: Mon, 13 Jan 2020 14:22:18 GMT
2020-02-06 10:33:23,405 DEBUG http-outgoing-0 << Backend-Timing: D=320 t=1579084179579408
2020-02-06 10:33:23,405 DEBUG http-outgoing-0 << Content-Encoding: gzip
2020-02-06 10:33:23,405 DEBUG http-outgoing-0 << Vary: Accept-Encoding
2020-02-06 10:33:23,405 DEBUG http-outgoing-0 << X-Varnish: 118503554 495852195
2020-02-06 10:33:23,406 DEBUG http-outgoing-0 << Age: 46437
2020-02-06 10:33:23,406 DEBUG http-outgoing-0 << X-Cache: cp3062 miss, cp3052 hit/600912
2020-02-06 10:33:23,406 DEBUG http-outgoing-0 << X-Cache-Status: hit-front
2020-02-06 10:33:23,407 DEBUG http-outgoing-0 << Server-Timing: cache;desc="hit-front"
2020-02-06 10:33:23,407 DEBUG http-outgoing-0 << Strict-Transport-Security: max-age=106384710; includeSubDomains; preload
2020-02-06 10:33:23,407 DEBUG http-outgoing-0 << Set-Cookie: WMF-Last-Access=06-Feb-2020;Path=/;HttpOnly;secure;Expires=Mon, 09 Mar 2020 00:00:00 GMT
2020-02-06 10:33:23,407 DEBUG http-outgoing-0 << Set-Cookie: WMF-Last-Access-Global=06-Feb-2020;Path=/;Domain=.wikipedia.org;HttpOnly;secure;Expires=Mon, 09 Mar 2020 00:00:00 GMT
2020-02-06 10:33:23,408 DEBUG http-outgoing-0 << X-Client-IP: 213.55.225.99
2020-02-06 10:33:23,418 DEBUG http-outgoing-0 << Set-Cookie: GeoIP=CH:ZH:Zurich:47.37:8.55:v4; Path=/; secure; Domain=.wikipedia.org
2020-02-06 10:33:23,418 DEBUG http-outgoing-0 << Accept-Ranges: bytes
2020-02-06 10:33:23,418 DEBUG http-outgoing-0 << Content-Length: 18800
2020-02-06 10:33:23,419 DEBUG http-outgoing-0 << Connection: keep-alive
2020-02-06 10:33:23,429 DEBUG ex-00000001: connection can be kept alive for -1 MILLISECONDS
2020-02-06 10:33:23,437 DEBUG Cookie accepted [WMF-Last-Access="06-Feb-2020", domain:www.wikipedia.org, path:/, expiry:Mon Mar 09 01:00:00 CET 2020]
2020-02-06 10:33:23,438 DEBUG Cookie accepted [WMF-Last-Access-Global="06-Feb-2020", domain:wikipedia.org, path:/, expiry:Mon Mar 09 01:00:00 CET 2020]
2020-02-06 10:33:23,438 DEBUG Cookie accepted [GeoIP="CH:ZH:Zurich:47.37:8.55:v4", domain:wikipedia.org, path:/, expiry:null]
----------------------------------------
200 OK
SSL protocol TLSv1.2
SSL cipher suite TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
2020-02-06 10:33:23,467 DEBUG http-outgoing-0: close connection GRACEFUL
2020-02-06 10:33:23,468 DEBUG ep-00000000: endpoint closed
2020-02-06 10:33:23,468 DEBUG ep-00000000: endpoint closed
2020-02-06 10:33:23,468 DEBUG ep-00000000: discarding endpoint
2020-02-06 10:33:23,468 DEBUG ep-00000000: releasing endpoint
2020-02-06 10:33:23,469 DEBUG ep-00000000: connection released [route: s->https://www.wikipedia.org:443][total available: 0; route allocated: 0 of 5; total allocated: 0 of 25]
2020-02-06 10:33:23,469 DEBUG Shutdown connection pool GRACEFUL
2020-02-06 10:33:23,469 DEBUG Connection pool shut down

【讨论】:

谢谢,你是说Conscrypt只能和HttpAsyncClient一起使用,不能和普通的HttpClient一起使用吗?理想情况下,我想弄清楚如何使它与常规 HttpClient 一起工作。 嗯。不,我不是这么说的,但我实际上从未使用 Conscrypt 提供程序测试过经典的 HttpClient。我会这样做并回复你。 谢谢!更好的是,找到一种方法在整个系统范围内用 Conscrypt 替换 JSSE 会变得更加容易,因此即使是常规的 HttpsUrlConnections 也可以在没有特殊配置的情况下使用 Conscrypt。 查看我的更新。 Conscrypt 基本上适用于我,无需任何特殊配置。 我接受了你的回答,因为它是如何使用 Conscrypt 的主要问题的答案。不幸的是,在 MacOS 上,您的确切代码仍然不适合我,我得到:Exception in thread "main" java.net.NoRouteToHostException: No route to host at java.base/sun.nio.ch.Net.connect0(Native Method)

以上是关于如何使用 Conscrypt 和 Apache HttpClient 5 来​​加速 TLS的主要内容,如果未能解决你的问题,请参考以下文章

找不到 TLS ALPN 提供程序;没有可用的 netty-tcnative、Conscrypt 或 Jetty NPN/ALPN

StrictMode 策略违规:android.os.strictmode.NonSdkApiUsedViolation: Lcom/android/org/conscrypt/ConscryptEn

如何使用 apache 403 错误作为带有 h​​taccess 的路由技术

Android 10 踩坑实录 &#128073; 2020-01-20

如何让groovysh与apache一起工作

使用apache 2.4.33和openssl 1.1.0h编译问题