服务器关闭使用 httpclient 和 Java 7 建立的连接 [英] Server closes connections made using httpclient and Java 7

查看:30
本文介绍了服务器关闭使用 httpclient 和 Java 7 建立的连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试连接到使用 SNI 提供证书的远程服务器.我注意到服务器关闭了在我使用 Java 7 编译和运行代码时建立的连接,而不是在我通过 Java 8 编译和运行它时.

I am trying to connect to a remote server that serves certificates using SNI. I noticed that the server is closing connections made when I compile and run code using Java 7 and not when I compile and run it via Java 8.

下面是我用来测试这个假设的代码.我切换 Java 版本并运行代码并得到不同的结果.

Below is the code that i made to test this assumption. I switch Java versions and run the code and get different results.

public static void getRequest() throws IOException, NoSuchAlgorithmException, KeyManagementException {
    String url = "https://sorry i can not share the exact url because of privacy concerns";

    HttpClient client = getClientInstance();
    HttpGet request = new HttpGet(url);

    HttpResponse response = client.execute(request);

    System.out.println("Response Code : "
            + response.getStatusLine().getStatusCode());

    BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));

    StringBuffer result = new StringBuffer();
    String line = "";
    while ((line = rd.readLine()) != null) {
        result.append(line);
    }
    System.out.println("####### the result is");
    System.out.println(result.toString());
}

private static org.apache.http.client.HttpClient getClientInstance() throws KeyManagementException, NoSuchAlgorithmException {
    RequestConfig defaultRequestConfig = RequestConfig.copy(RequestConfig.DEFAULT)
            .setConnectTimeout(60 * 1000)
            .setSocketTimeout(60 * 1000)
            .setConnectionRequestTimeout(60 * 1000)
            .build();

    return HttpClientBuilder.create().setDefaultRequestConfig(defaultRequestConfig).build();
}

有人遇到过这样的问题并解决了吗?我知道最终的解决方法是使用 Java 8,但这不是我在当前时间限制内可以完成的任务,因为我正在调试的整个代码库非常庞大,而且依赖项可能不适用于 Java 7.

Has someone ever experienced such an issue and fixed it? I know the ultimate fix would be to use Java 8 but that's not a task that I can do within my current time constraints since the entire codebase i was debugging is huge and has dependencies that might not work well with Java 7.

抛出的异常如下;

*** ClientHello, TLSv1
RandomCookie:  GMT: 1472095425 bytes = { 254, 51, 194, 246, 77, 6, 185, 8, 224, 187, 85, 225, 133, 128, 122, 1, 245, 13, 230, 239, 156, 93, 164, 184, 251, 159, 111, 60 }
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_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, 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, 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: lasclev.org]
***
main, WRITE: TLSv1 Handshake, length = 169
main, handling exception: java.net.SocketException: Connection reset
main, SEND TLSv1 ALERT:  fatal, description = unexpected_message
main, WRITE: TLSv1 Alert, length = 2
main, Exception sending alert: java.net.SocketException: Broken pipe
main, called closeSocket()
java.net.SocketException: Connection reset
    at java.net.SocketInputStream.read(SocketInputStream.java:196)
    at java.net.SocketInputStream.read(SocketInputStream.java:122)
    at sun.security.ssl.InputRecord.readFully(InputRecord.java:442)
    at sun.security.ssl.InputRecord.read(InputRecord.java:480)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:934)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1332)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1359)

下面也是我之前进行的 SSL Labs 测试的屏幕截图.

Also below is a screenshot of the SSL Labs test that i carried out earlier.

推荐答案

您没有显示 SSLLabs 报告中列出支持的协议的部分,但我打赌您会发现该服务器仅支持 TLSv1.2 或者也许TLSv1.2 和 TLSv1.1,但不是 TLSv1.0.特别是,处理受 PCI DSS 约束的支付交易的系统通常被禁止使用 TLSv1.0(又名早期 TLS"),这显然是由于对 BEAST 的过度反应(尽管它不值得,但在 NVD 中仍为 4.3).尽管在这种情况下,服务器应该给出警报 70 或者 71 或 40,而不仅仅是重置(或关闭).Java7 (JSSE) 客户端默认不执行 TLSv1.2 或 TLSv1.1.

You didn't show the part of the SSLLabs report where it lists protocols supported, but I bet you'll find this server supports only TLSv1.2 or maybe TLSv1.2 and TLSv1.1, but not TLSv1.0. In particular, systems handling payment transactions subject to PCI DSS are generally prohibited from using TLSv1.0 (aka 'Early TLS') apparently due to an overreaction to BEAST (which remains 4.3 in NVD although it doesn't deserve to). Although in this case the server should give alert 70 or maybe 71 or 40 not just reset (or close). Java7 (JSSE) client by default does not do TLSv1.2 or TLSv1.1.

这可能取决于 HttpClient 的版本——我有 4.5——但我认为你可以:

It may depend on the version of HttpClient -- I have 4.5 -- but I think you can either:

  • 创建一个适当配置的 SSLConnectionSocketFactory.setSSLSocketFactory,或者

.useSystemProperties(true) 并适当地设置 sysprop https.protocolsTLSv1.2TLSv1.1、TLSv1.2(也被javax.net.HttpsURLConnection 使用),但这可能会影响你不想要的其他东西(请参阅useSystemProperties 的javadoc>)

.useSystemProperties(true) and set sysprop https.protocols as appropriate either TLSv1.2 or TLSv1.1,TLSv1.2 (also used by javax.net.HttpsURLConnection), but this may affect other things you don't want (see the javadoc for useSystemProperties)

这篇关于服务器关闭使用 httpclient 和 Java 7 建立的连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆