Apache http 客户端默认值不适用于 sni



主要问题

最新的4.x apachehttp客户端是否存在我不知道的错误?或者我错过了一个让sni去上班的环境

在同一jvm中(在本例中为1.7.0_45(。

我运行以下两段代码来获取一个https url,该url需要SNI才能正确连接。第一段代码使用java的内建java.net.*方法,第二段代码使用org.apache.http.*(4.5版(方法。

使用java.net.*的方法

public final class JavaNetHitApi extends BaseHitApi {
    @Override
    public JSONObject hitAPI(final String url) throws IOException {
        URL toUse = new URL(url);
        URLConnection conn = toUse.openConnection();
        final String result = readToString(conn.getInputStream());
        JSONObject toReturn = new JSONObject(result);
        return toReturn;
    }
}

使用org.apache.http.*的方法

public final class ApacheHttpHitApi extends BaseHitApi {
    @Override
    public JSONObject hitAPI(final String url) throws IOException {
        final HttpGet httpGet = new HttpGet(url);
        try (final CloseableHttpClient httpclient = HttpClients.createDefault();
                final CloseableHttpResponse response = httpclient.execute(httpGet)) {
            String result = readToString(response.getEntity().getContent());
            JSONObject toReturn = new JSONObject(result);
            return toReturn;
        }
    }
}

对于第一种情况(java.net.*(,它运行良好,返回时没有任何问题。

对于第二种情况(org.apache.http.*(,它抛出以下错误:

javax.net.ssl.ssl握手异常:收到致命警报:握手失败

请记住,这是在相同的JVM上运行的,具有相同的启用sni的设置等。我在搜索中遇到的唯一解释都是关于从java 1.6->1.7,或1.7->1.8,或在系统上启用sni,等等。在这种情况下,所有这些变量都被消除了,因为这两段代码的底层系统设置是相同的。

主要问题回顾

最新的4.x apachehttp客户端是否存在我不知道的错误?或者我错过了一个让sni去上班的环境


使用运行时

"-Djavax.net.debug=全部">

flag,我可以看到这两种方法的不同之处,即java.net.*方法抛出了一行:

扩展服务器名称,服务器名称:[主机名称:模糊子域。执行api。us-west-2.amazonaws.com]

而apachehttp客户端则没有。

输出片段包含在下面以供参考。

java.net.*输出

Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
main, setSoTimeout(0) called
%% No cached client session
*** ClientHello, TLSv1
RandomCookie:  GMT: 1424292809 bytes = { 117, 134, 25, 51, 251, 228, 170, 18, 240, 70, 32, 245, 131, 90, 128, 105, 26, 220, 234, 92, 81, 47, 129, 195, 17, 137, 210, 125 }
Session ID:  {}
Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, SSL_RSA_WITH_RC4_128_SHA, TLS_ECDH_ECDSA_WITH_RC4_128_SHA, TLS_ECDH_RSA_WITH_RC4_128_SHA, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_RC4_128_MD5, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods:  { 0 }
Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1}
Extension ec_point_formats, formats: [uncompressed]
Extension server_name, server_name: [host_name: obfuscatedsubdomain.execute-api.us-west-2.amazonaws.com]
***

apache.org.http.*输出

main, setSoTimeout(0) called
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
%% No cached client session
*** ClientHello, TLSv1
RandomCookie:  GMT: 1424293231 bytes = { 222, 180, 202, 14, 219, 36, 94, 157, 23, 55, 5, 98, 165, 33, 227, 160, 201, 191, 122, 194, 241, 154, 216, 137, 159, 81, 208, 143 }
Session ID:  {}
Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, SSL_RSA_WITH_RC4_128_SHA, TLS_ECDH_ECDSA_WITH_RC4_128_SHA, TLS_ECDH_RSA_WITH_RC4_128_SHA, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_RC4_128_MD5, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods:  { 0 }
Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1}
Extension ec_point_formats, formats: [uncompressed]
***

最终的问题是,另一个依赖项不仅使用了不同版本的httpclient,而且还将其打包到其jar中,而没有将其列为可传递依赖项。(也就是说,当你去检查pom依赖层次结构时,它不会显示出来,所以它不能被标记为"使用过的版本"(。

有问题的依赖性是:

<dependency>
    <groupId>com.google.gwt</groupId>
    <artifactId>gwt-dev</artifactId>
    <version>2.7.0</version>
</dependency>

它的jar中包含apachehttp的代码,pom中未列出这些代码。它引用的版本是4.3.1,它展示了这个问题。(4.3.2及以后版本不适用(。

有两种解决方法:

  1. 在pom.xml

  2. 从pom.xml 中删除gwt-dev依赖项

相关内容

最新更新