2016-01-07 4 views
15

Ich befolge viele Links auf stackoverflow und habe viele Lösungen ausprobiert, aber keine von ihnen hat für mich funktioniert. Ich verwende WSO2 API manager Version 1.9.1. Ich sehe folgenden Fehler:javax.net.ssl.SSLPeerUnverifiedException: Hostname stimmt nicht mit dem vom Peer angegebenen Zertifikat überein

Exception in thread "main" javax.net.ssl.SSLPeerUnverifiedException: Host name 'XXXXXXXXX' does not match the certificate subject provided by the peer (CN=localhost, O=WSO2, L=Mountain View, ST=CA, C=US) 
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.verifyHostname(SSLConnectionSocketFactory.java:465) 
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:395) 
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:353) 
    at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:134) 
    at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:353) 
    at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:380) 
    at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236) 
    at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184) 
    at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88) 
    at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110) 
    at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184) 
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82) 
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:107) 
    at com.java.pushNotifications.WSO2DemoClient.main(WSO2DemoClient.java:49) 

Ich entwickelte den folgenden Java-Code. Bitte hilf mir, was hier falsch läuft. Ich muss eine unsichere Verbindung herstellen und Verbindungen zu SSL-Sites zulassen, ohne certs.

public static void main(String[] args) throws ClientProtocolException, IOException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException { 
     SSLContextBuilder builder = new SSLContextBuilder(); 
     builder.loadTrustMaterial(null, new TrustSelfSignedStrategy()); 
     SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build()); 

     Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create() 
       .register("http", new PlainConnectionSocketFactory()) 
       .register("https", sslsf) 
       .build(); 

     PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry); 
     cm.setMaxTotal(2000);//max connection 

    CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf) 
       .setConnectionManager(cm).build(); 

     HttpGet httpGet = new HttpGet("https://XXXXXXXXXX:8243/token"); 
     CloseableHttpResponse response = httpclient.execute(httpGet); 

     String json =" {\"data\":\"grant_type=password&username=test&password=test123\"}"; 

     try { 
      HttpPost httpost = new HttpPost(url); 
      httpost.setHeader("Content-Type", "application/x-www-form-urlencoded"); 
      httpost.setHeader("Authorization", "Basic XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"); 

      httpost.setEntity(new StringEntity(json)); 

      HttpResponse httpResponse = httpclient.execute(httpost); 

      System.out.println(httpResponse.getStatusLine()); 
     } 
     finally { 
      response.close(); 
     } 

     String responseString1 = new BasicResponseHandler().handleResponse(response); 
     System.out.println("Response : "+responseString1); 
    } 
+0

Sie müssen den Hostnamen in das Zertifikat sowie das Thema alternative Namen in den Host-Namen + vergleichen, die Sie in Ihrem Code aufrufen (siehe oben " XXXXXXXXXXXXXX "). Diese scheinen nicht zu passen. Das Konzept dahinter ist die Verifizierung des HTTP-Hostnamens, siehe [link] (https://tools.ietf.org/html/rfc6125) –

+0

Dies funktioniert nur, weil Sie die Option "-k" verwenden, die mit "-" identisch ist. -unsicher". Dann wird die Zertifikatsprüfung nicht durchgeführt. –

+0

Siehe [link] (http://stackoverflow.com/questions/6457471/java-httpclient-error-for-no-ssl-certificate-found-using-certificate-as-string) –

Antwort

12

Ersetzen Sie diese

CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf) 
      .setConnectionManager(cm).build(); 

mit

CloseableHttpClient httpclient = HttpClients.custom() 
      .setSSLSocketFactory(sslsf) 
      .setConnectionManager(cm) 
      .setHostnameVerifier(SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER) 
      .build(); 

Wenn das Zertifikat nicht signiert ist (nicht einmal selbst signiertes), dann können Sie tun

import java.security.cert.CertificateException; 
import java.security.cert.X509Certificate; 

public class TrustAllStrategy implements TrustStrategy { 
    @Override 
    public boolean isTrusted(X509Certificate[] chain, String authType) 
      throws CertificateException { 
     return true; 
    } 
} 

Dann

builder.loadTrustMaterial(new TrustAllStrategy()); 

EDIT: Diese

SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
      sslcontext, //for you this is builder.build() 
      SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER 
); 
+0

Welche Version von HttpClient du bist Vorschlagen für oben zu verwenden? –

+0

4.3.x oder 4.4.x Ich denke beide funktionieren, ich habe den HttpClient nicht über diesen Versionen benutzt. Ich benutzte 4.3.5. – EpicPandaForce

+0

Thnx, jetzt sehe ich Ausnahme im Thread "Haupt" javax.net.ssl.SSLException: Hostname im Zertifikat stimmte nicht überein: ! =

25

Ich habe eine Stunde lang versucht, das gleiche Problem zu beheben. Dies ist, was ich komme mit:

final SSLConnectionSocketFactory sslsf; 
try { 
    sslsf = new SSLConnectionSocketFactory(SSLContext.getDefault(), 
      NoopHostnameVerifier.INSTANCE); 
} catch (NoSuchAlgorithmException e) { 
    throw new RuntimeException(e); 
} 

final Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create() 
     .register("http", new PlainConnectionSocketFactory()) 
     .register("https", sslsf) 
     .build(); 

final PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry); 
cm.setMaxTotal(100); 
httpClient = HttpClients.custom() 
     .setSSLSocketFactory(sslsf) 
     .setConnectionManager(cm) 
     .build(); 

Hoffentlich es funktioniert und verwendet keine veralteten Code (Httpclient 4.4.1).

+0

Sie sparen meinen Tag! Ich weiß nicht, warum das nicht viele Stimmen hat ... Wie 30 Minuten mit diesem verloren. – camposer

+0

diese Lösung funktionierte für mich. – Shek

+0

arbeitete für mich wie ein Charme. – krupalpatel86

3

ist, was ich kam mit:

SSLContextBuilder sslcontext = new SSLContextBuilder(); 
sslcontext.loadTrustMaterial(null, new TrustSelfSignedStrategy()); 
httpclient = HttpAsyncClients.custom().setSSLContext(sslcontext.build()).setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE) 
     .build(); 
3
Lösungen

Vielen Dank an alle. Ich habe seit 1,5 Tagen alle verfügbaren Lösungen online getestet und es hat jetzt endlich funktioniert. Hier ist der Arbeitscode

SSLContextBuilder builder = new SSLContextBuilder(); 
builder.loadTrustMaterial(null, new TrustSelfSignedStrategy()); 
SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(builder.build(), NoopHostnameVerifier.INSTANCE); 
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create() 
      .register("http", new PlainConnectionSocketFactory()) 
      .register("https", sslConnectionSocketFactory) 
      .build(); 

PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry); 
cm.setMaxTotal(100); 
CloseableHttpClient httpclient = HttpClients.custom() 
      .setSSLSocketFactory(sslConnectionSocketFactory) 
      .setConnectionManager(cm) 
      .build(); 
HttpPost httpPost = new HttpPost(url); 
httpPost.setEntity(postEntity); 
httpPost.expectContinue(); 
CloseableHttpResponse response = httpclient.execute(httpPost); 
2

Nachdem die meisten der vorgeschlagenen Lösung auf dieser Seite und andere damit zusammenhängende Diskussionen versuchen Stackoverflow, fand ich AJC Antwort oben genannten Arbeiten mit Apache Httpclient Version 4.5.

Grund: Beim Erstellen von SSLConnectionSocketFactory, wenn der HostVerifier nicht im Konstruktor angegeben ist, wird es nicht festgelegt und der DefaultHostVerifier wird verwendet. Die Linie 3 der AJC-Lösung macht also den Unterschied.

(Atleast das ist das Verhalten in Apache Httpclient 4.5.3)

+1

Ich nehme an, Sie hätten die Lösung von AJC einfach kommentiert, hätten Sie genug Reps, um das zu tun. Netter Touch, um den Grund hinzuzufügen, um zu verbessern, was sonst erreicht werden könnte, indem man einfach AJC-Lösung upboost. – leanne

+0

Danke für diese Antwort. Es brachte mich dazu, über den Grund des Scheiterns nachzudenken. In meinem Fall verwendete der Server ein Wildcard-Zertifikat und daher behob ich das Problem mit "BrowserCompatHostnameVerifier" behoben. Der "BrowserCompatHostnameVerifier" erlaubt Wildcard-Zertifikate genau wie ein Browser. – buzz

Verwandte Themen