2017-03-07 5 views
1

SNI를 사용하여 인증서를 제공하는 원격 서버에 연결하려고합니다. 서버가 Java 7을 사용하여 코드를 컴파일하고 실행할 때 서버를 닫고 Java 8을 사용하여 컴파일 및 실행하지 않을 때 나타났습니다.서버가 httpclient 및 Java 7을 사용하여 만든 연결을 닫습니다.

다음은이 가정을 테스트하기 위해 작성한 코드입니다. 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(); 
} 

누군가 이러한 문제를 경험하고 해결 했습니까? 궁극적 인 해결 방법은 Java 8을 사용하는 것이지만 현재 디버깅 중이던 전체 코드베이스가 크고 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 테스트의 스크린 샷이 있습니다. SSL Labs test fragment

답변

2

SSLLabs 보고서에 지원되는 프로토콜 목록이 표시되지 않았지만이 서버는 TLSv1.2 또는 TLSv1.2 및 TLSv1.1 만 지원하지만 TLSv1은 지원하지 않을 것입니다. .0. 특히, PCI DSS에 따른 지불 거래를 처리하는 시스템은 일반적으로 BEAST에 대한 과잉 반응으로 인해 TLSv1.0 (일명 'Early TLS')을 사용하는 것이 금지되어 있습니다 (NVD에서는 4.3으로 남아 있음). 이 경우 서버 에 경고 70을 주거나 71 또는 40을 재설정 (또는 닫기)하지 않아야합니다. Java7 (JSSE) 클라이언트는 기본적으로 TLSv1.2 또는 TLSv1.1을 수행하지 않습니다.

그것은 HttpClient를의 버전에 따라 달라질 수 있습니다

- 난 4.5이 -하지만 난 당신이 할 수있는 생각 중 하나

  • 만들 적절 SSLConnectionSocketFactory과에 .setSSLSocketFactory, 또는

  • 구성 .useSystemProperties(true)을 사용하고 sysprop https.protocolsTLSv1.2 또는 TLSv1.1,TLSv1.2 (javax.net.HttpsURLConnection도 사용)으로 설정하십시오. 그러나 원하지 않는 다른 사항에 영향을 줄 수 있습니다 (useSystemProperties의 javadoc 참조).

+0

당신이 완전히 제안하는 것은 나에게 도움이되지 않습니다. 원격 서버는 내가 제어 할 수없는 것입니다. 시간 제약 때문에 나는'Runtime.getRuntime(). exec'을 통해 말풍선을 사용하여 이것에 대한 불쾌한 해결 방법을 만들었다. – ivanorone

관련 문제