简体   繁体   English

服务器关闭使用httpclient和Java 7建立的连接

[英]Server closes connections made using httpclient and Java 7

I am trying to connect to a remote server that serves certificates using SNI. 我正在尝试连接到使用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 7编译和运行代码时建立的连接,而不是当我通过Java 8编译和运行代码时关闭。

Below is the code that i made to test this assumption. 下面是我为测试此假设而编写的代码。 I switch Java versions and run the code and get different results. 我切换Java版本并运行代码并获得不同的结果。

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

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. 我知道最终的解决方法是使用Java 8,但这不是我可以在当前时间限制内完成的任务,因为我调试的整个代码库非常庞大,并且依赖项可能不适用于Java 7。

The exception being thrown is as below; 抛出的异常如下所示;

*** 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)

Also below is a screenshot of the SSL Labs test that i carried out earlier. 以下也是我之前进行的SSL实验室测试的屏幕截图。 SSL Labs测试片段

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. 您没有在SSLLabs报告的一部分中列出支持的协议,但是我敢打赌,您会发现该服务器仅支持TLSv1.2或TLSv1.2和TLSv1.1,但不支持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). 特别是,显然,由于对BEAST的反应过度(尽管它不值得在NVD中保留4.3),通常禁止处理受PCI DSS约束的支付交易的系统使用TLSv1.0(又名“早期TLS”)。 Although in this case the server should give alert 70 or maybe 71 or 40 not just reset (or close). 尽管在这种情况下,服务器应该发出警报70或71或40,而不仅仅是重置(或关闭)。 Java7 (JSSE) client by default does not do TLSv1.2 or TLSv1.1. 默认情况下,Java7(JSSE)客户端不执行TLSv1.2或TLSv1.1。

It may depend on the version of HttpClient -- I have 4.5 -- but I think you can either: 它可能取决于HttpClient的版本-我有4.5-但我认为您可以:

  • create an appropriately configured SSLConnectionSocketFactory and .setSSLSocketFactory to it, or 创建一个适当配置的SSLConnectionSocketFactory.setSSLSocketFactory ,或者

  • .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 ) .useSystemProperties(true)并根据需要将sysprop https.protocols设置为TLSv1.2TLSv1.1,TLSv1.2 (也由javax.net.HttpsURLConnection ),但这可能会影响您不想要的其他事情(请参阅用于useSystemProperties javadoc)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM