2016-08-06 18 views
1

HttpClient를 사용하여 SNI 사이트에서 리소스를 가져올 수 없습니다. 가져 오려고하는 URL은 https://dabar.srce.hr/, https://www.lutrija.hr/cms/splash입니다. javax.net.ssl.SSLHandshakeException : 수신 치명적인 경고 :서버에서 SNI (Server Name Indication) 확장을 사용하는 경우 HttpClient 4.5.2 및 JDK 1.8에서 HTTPS 웹 재생을 가져 오는 방법은 무엇입니까?

는이 오류 얻을 handshake_failure을

나는 문서는 상자에서 다음과 같이 작동합니다 (그리고 비 SNI HTTPS 사이트에 대한 작동 알고있는 것처럼) : 나는 SSLConnectionSocket을 무시하려

System.setProperty("jsse.enableSNIExtension", "true");       

: 내가 명시 적으로 SNIExtension 수 있도록 노력

url = "https://dabar.srce.hr/"; 
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() { 
    // trust all certificates 
    public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { 
     return true; 
    } 
}).build(); 
SSLConnectionSocketFactory sslSF = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE); 
CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslSF).build(); 
HttpGet httpGet = new HttpGet(url); 
CloseableHttpResponse response = httpclient.execute(httpGet); 
System.out.println(response.getStatusLine().toString()); 
HttpEntity entity = response.getEntity(); 
System.out.println(EntityUtils.toString(entity)); 

공장 :

SSLConnectionSocketFactory sslSF = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE) { 
    String targetHost = ""; 
    @Override 
    public Socket createLayeredSocket(Socket socket, String target, int port, HttpContext context) 
       throws IOException { 
     this.targetHost = target; 
     return super.createLayeredSocket(socket, target, port, context); 
    } 
    @Override 
    protected void prepareSocket(SSLSocket socket) throws IOException { 
     try { 
      PropertyUtils.setProperty(socket, "host", this.targetHost); 
     } catch (Exception ex) { 
     } 
     super.prepareSocket(socket); 
    } 
    @Override 
    public Socket connectSocket(int connectTimeout, Socket socket, HttpHost host, InetSocketAddress remoteAddress, InetSocketAddress localAddress, HttpContext context) 
     throws IOException { 
     if (socket instanceof SSLSocket) { 
      try { 
       PropertyUtils.setProperty(socket, "host", host.getHostName()); 
      } catch (NoSuchMethodException e) { 
      } catch (IllegalAccessException e) { 
      } catch (InvocationTargetException e) { 
     } 
    } 
    return super.connectSocket(connectTimeout, socket, host, remoteAddress, 
        localAddress, context); 
    } 
}; 

무엇이 누락 되었습니까?

답변

2

같은 문제가 발생했습니다. 이 사용자 정의 SSLConnectionSocketFactory 나를 위해 그것을 고정 :

 
public class TrustAllSslSocketFactory extends SSLConnectionSocketFactory { 

    static final HostnameVerifier ALL_HOSTNAME_VERIFIER = (String hostname, SSLSession session) -> true; 

    public TrustAllSslSocketFactory(SSLContext sslContext) { 
     super(sslContext, ALL_HOSTNAME_VERIFIER); 
    } 

    @Override 
    protected void prepareSocket(SSLSocket socket) throws IOException { 
       String hostName = socket.getInetAddress().getHostName(); 
     SNIHostName sniHostName = new SNIHostName(hostName); 
     List serverNames = new ArrayList(1); 
     serverNames.add(sniHostName); 
     SSLParameters sslParameters = socket.getSSLParameters(); 
     sslParameters.setServerNames(serverNames); 
     socket.setSSLParameters(sslParameters); 
    } 


} 

참조 http://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#SNIExamples