2016-08-06 4 views
1

Ich kann Ressourcen von SNI-Sites mit HttpClient nicht abrufen. URLs, die ich abrufen möchte, sind: https://dabar.srce.hr/, https://www.lutrija.hr/cms/splash.Wie hole ich HTTPS-Web-Resumes mit HttpClient 4.5.2 & JDK 1.8, wenn der Server die Server Name Indication (SNI) -Erweiterung verwendet?

ich diesen Fehler: javax.net.ssl.SSLHandshakeException: Schwerwiegender Alarm empfangen: handshake_failure

Wie ich verstehe die Dokumentation soll es aus dem Kasten heraus, wie dies funktioniert (und es funktioniert für nicht sni https-Sites):

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

ich habe versucht, explizit SNIExtension aktivieren:

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

ich versuchte zwingende SSLConnectionSocket Fabrik:

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

Was vermisse ich?

Antwort

2

Ich stieß auf das gleiche Problem. Dieser Brauch SSLConnectionSocketFactory es für mich festgelegt:

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


} 

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

Verwandte Themen