2016-01-07 42 views
15

Seguo molti link su StackOverflow e ho provato molte soluzioni, ma nessuna ha funzionato per me. Sto usando la versione WSO2 API manager1.9.1. Sto affrontando il seguente errore:javax.net.ssl.SSLPeerUnverifiedException: il nome dell'host non corrisponde all'oggetto del certificato fornito dal peer

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) 

Ho sviluppato il seguente codice Java. Per favore aiutami cosa sta andando storto qui. Devo connettermi in modo non sicuro e consentire connessioni a siti SSL senza 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

È necessario confrontare il nome host nel certificato più il soggetto nomi alternativi al suo interno + il nome host che si chiama nel codice (sopra " XXXXXXXXXXXXXX "). Quelli non sembrano corrispondere. Il concetto alla base è la verifica del nome host http, vedi [link] (https://tools.ietf.org/html/rfc6125) –

+0

Questo funziona solo perché stai usando l'opzione "-k" che è la stessa di "- -insicuro". Quindi la verifica del certificato non viene eseguita. –

+0

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

risposta

12

Sostituire questo

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

con

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

Se il certificato non è firmato (nemmeno auto-firmato), allora si può fare

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

Quindi

builder.loadTrustMaterial(new TrustAllStrategy()); 

EDIT: questo

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

Quale versione di HttpClient sei suggerendo di usare per sopra? –

+0

4.3.xo 4.4.x Penso che entrambi funzionerebbero, non ho usato HttpClient sopra quelle versioni. Stavo usando 4.3.5. – EpicPandaForce

+0

Thnx, ora vedo l'eccezione nel thread "main" javax.net.ssl.SSLException: il nome host nel certificato non corrisponde: ! =

25

Ho trascorso un'ora cercando di risolvere lo stesso problema. Questo è ciò che mi è venuta in mente:

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

Speriamo che funziona e non utilizza alcun codice deprecato (HttpClient 4.4.1).

+0

Si salva la mia giornata! Non so perché questo non ha molti voti ... Come 30 minuti persi con questo. – camposer

+0

questa soluzione ha funzionato per me. – Shek

+0

ha funzionato per me come un fascino. – krupalpatel86

3

Questo è ciò che mi si avvicinò con:

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

Grazie a tutte le soluzioni. Ho provato tutte le soluzioni disponibili online per 1,5 giorni ora e finalmente ha funzionato ora. Ecco il codice di lavoro

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

Dopo aver provato la maggior parte della soluzione proposta in questa pagina e altre discussioni StackOverflow correlate, ho trovato la risposta di AJC sopra funziona con Apache HttpClient versione 4.5.

Causa: Durante la creazione di SSLConnectionSocketFactory se HostVerifier non è specificato nel costruttore, non viene impostato e viene utilizzato DefaultHostVerifier. Quindi la linea 3 della soluzione di AJC fa la differenza.

(almeno questo è il comportamento in HttpClient Apache 4.5.3)

+1

Suppongo che tu abbia semplicemente commentato la soluzione di AJC, avevi abbastanza rappresentanti per farlo. Un bel tocco per aggiungere il motivo per migliorare ciò che altrimenti sarebbe stato possibile semplicemente facendo salire la soluzione di AJC. – leanne

+0

Grazie per questa risposta. Mi ha fatto pensare alla ragione del fallimento. Nel mio caso, il server utilizzava un certificato con caratteri jolly e pertanto, utilizzando "BrowserCompatHostnameVerifier", è stato risolto il problema. Il "BrowserCompatHostnameVerifier" consente i certificati jolly proprio come farebbe un browser. – buzz