2013-08-08 10 views
26

Ci sono dozzine di post su questo problema (javax.net.ssl.SSLPeerUnverifiedException: Nessun certificato peer) ma non ho trovato nulla che funzioni per me.Fissaggio sicuro: javax.net.ssl.SSLPeerUnverifiedException: Nessun certificato peer

Molti post (come this e this) "risolvono" questo consentendo l'accettazione di tutti i certificati, ma, naturalmente, questa non è una buona soluzione per qualcosa di diverso dal test.

Altri sembrano abbastanza localizzati e non funzionano per me. Spero davvero che qualcuno abbia qualche intuizione che mi manca.

Quindi, il mio problema: sto testando su un server accessibile solo attraverso la rete locale, collegandolo tramite HTTPS. Effettuare la chiamata di cui ho bisogno tramite il browser funziona correttamente. Non mi lamento dei certificati e se controlli i certificati, tutto sembra a posto.

Quando provo sul mio dispositivo Android, ho javax.net.ssl.SSLPeerUnverifiedException: No peer certificate

Ecco il codice che lo chiama:

StringBuilder builder = new StringBuilder(); 
builder.append(/* stuff goes here*/); 

httpGet.setEntity(new UrlEncodedFormEntity(nameValuePairs)); 
ResponseHandler<String> responseHandler = new BasicResponseHandler(); 

// Execute HTTP Post Request. Response body returned as a string 
HttpClient httpClient = MyActivity.getHttpClient(); 
HttpGet httpGet = new HttpGet(builder.toString()); 

String jsonResponse = httpClient.execute(httpGet, responseHandler); //Line causing the Exception 

Il mio codice per MyActivity.getHttpClient():

protected synchronized static HttpClient getHttpClient(){ 
    if (httpClient != null) 
     return httpClient; 

    HttpParams httpParameters = new BasicHttpParams(); 
    HttpConnectionParams.setConnectionTimeout(httpParameters, TIMEOUT_CONNECTION); 
    HttpConnectionParams.setSoTimeout(httpParameters, TIMEOUT_SOCKET); 
    HttpProtocolParams.setVersion(httpParameters, HttpVersion.HTTP_1_1); 

    //Thread safe in case various AsyncTasks try to access it concurrently 
    SchemeRegistry schemeRegistry = new SchemeRegistry(); 
    schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); 
    schemeRegistry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443)); 
    ClientConnectionManager cm = new ThreadSafeClientConnManager(httpParameters, schemeRegistry); 

    httpClient = new DefaultHttpClient(cm, httpParameters); 

    CookieStore cookieStore = httpClient.getCookieStore(); 
    HttpContext localContext = new BasicHttpContext(); 
    localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore); 

    return httpClient; 
} 

Qualsiasi aiuto sarebbe molto apprezzato.

Modifica

anche solo per citare ho avuto altri problemi SSL con un'altra applicazione, ma aggiungendo la parte SchemeRegistry riparato per me prima.

Edit 2

Finora ho testato solo su Android 3.1, ma ho bisogno di questo per lavorare su Android 2.2+ prescindere. Ho appena provato il browser sulla mia scheda Android (Android 3.1) e si lamenta del certificato. Va bene sul mio browser pc, ma non sul browser Android o nella mia app.

Edit 3

'venuto fuori il browser iOS lamenta anche su di esso. Sto iniziando a pensare che sia un problema di catena di certificati qui descritto (SSL certificate is not trusted - on mobile only)

+0

questo problema a causa di https m ho ragione ?? –

+0

Sì, mi sto connettendo tramite https. Aggiornerò la domanda –

+0

Prova questo: https://stackoverflow.com/a/38598593/2301721 – ashishdhiman2007

risposta

5

Prova sottostante Codice: -

 BasicHttpResponse httpResponse = null; 

     HttpPost httppost = new HttpPost(URL); 

     HttpParams httpParameters = new BasicHttpParams(); 
     // Set the timeout in milliseconds until a connection is 
     // established. 
     int timeoutConnection = ConstantLib.CONNECTION_TIMEOUT; 
     HttpConnectionParams.setConnectionTimeout(httpParameters, 
       timeoutConnection); 
     // Set the default socket timeout (SO_TIMEOUT) 
     // in milliseconds which is the timeout for waiting for data. 
     int timeoutSocket = ConstantLib.CONNECTION_TIMEOUT; 
     HttpConnectionParams 
       .setSoTimeout(httpParameters, timeoutSocket); 

     DefaultHttpClient httpClient = new DefaultHttpClient(
       httpParameters); 
     List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(); 
     nameValuePairs.add(new BasicNameValuePair(ConstantLib.locale, 
       locale)); 
+1

Ho appena provato, anche se utilizzando un HttpGet e succede ancora –

+0

Ma è wrks per me –

+4

Cool. Ho app che funzionano anche su https per me ma non questa volta, motivo per cui sto facendo la domanda –

4

Nel mio caso tutto utilizzato per funzionare bene. All'improvviso, dopo 2 giorni, il mio dispositivo non ha mostrato alcun sito https o link immagine.

Dopo alcune indagini risulta che le mie impostazioni dell'ora non erano aggiornate sul dispositivo.

Ho modificato le mie impostazioni dell'ora correttamente e ha funzionato.

0

Ho avuto questa eccezione quando ho usato certificato autofirmato + indirizzo IP. Basta aggiungere queste righe

HostnameVerifier allHostsValid = new HostnameVerifier() { 
      @Override 
      public boolean verify(String hostname, SSLSession session) { 
       return true; 
      } 
     }; 
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid); 

e il tuo HttpURLConnection funzionerà. Questo trucco non è correlato alla convalida contro CA! Quindi, se specifico CA errata e utilizzo quel trucco, otterrò un'altra eccezione. Così i resti host attendibile

Solo nel caso, lascerò il codice per specificare il proprio CA qui:

String certStr = context.getString(R.string.caApi); 
X509Certificate ca = SecurityHelper.readCert(certStr); 

TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); 
ks.load(null); 
ks.setCertificateEntry("caCert", ca); 

tmf.init(ks); 

SSLContext sslContext = SSLContext.getInstance("TLS"); 
sslContext.init(null, tmf.getTrustManagers(), null); 
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory()); 

Non dimenticare di utilizzare la funzione buildTypes fresco e posizionare diversi CA per il debug/release nella cartella res .

Problemi correlati