2013-08-08 16 views
26

Istnieją dziesiątki postów dotyczących tego problemu (javax.net.ssl.SSLPeerUnverifiedException: Brak certyfikatu równorzędnego), ale nie znalazłem niczego, co będzie dla mnie działało.Bezpieczne naprawianie: javax.net.ssl.SSLPeerUnverifiedException: Brak certyfikatu równorzędnego

"Wiele postów (takich jak this i this) rozwiązuje ten problem, umożliwiając akceptację wszystkich certyfikatów, ale oczywiście nie jest to dobre rozwiązanie do innych celów niż testowanie.

Inne wydają się dość zlokalizowane i nie działają dla mnie. Naprawdę mam nadzieję, że ktoś ma wgląd w to, czego mi brakuje.

Mój problem: testuję na serwerze dostępnym tylko przez sieć lokalną, łącząc się przez HTTPS. Wykonanie połączenia, którego potrzebuję za pośrednictwem przeglądarki, działa dobrze. Bez narzekania na certyfikaty i jeśli sprawdzasz certyfikaty, wszystko wygląda dobrze.

Kiedy próbuję na urządzeniu z Androidem, mam javax.net.ssl.SSLPeerUnverifiedException: No peer certificate

Oto kod, który wywołuje go:

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 

Mój kod 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; 
} 

Każda pomoc będzie znacznie docenione.

Edit

Również tylko wspomnieć, miałem inne problemy SSL z innej aplikacji, ale dodając część SchemeRegistry stałe to dla mnie wcześniej.

Edycja 2

Jak dotąd testowane tylko na Androida 3.1, ale muszę to działa na Androidzie 2.2+ niezależnie. Właśnie testowałem w przeglądarce na mojej karcie Android (Android 3.1) i skarży się na certyfikat. To działa dobrze w mojej przeglądarce, ale nie w przeglądarce Androida ani w mojej aplikacji.

Edycja 3

Okazuje się, że przeglądarka iOS skarży się również na ten temat. Zaczynam myśleć, że jest to kwestia Łańcuch certyfikatów opisane tutaj (SSL certificate is not trusted - on mobile only)

+0

ten problem ze względu na https m i right ?? –

+0

Tak Łączę się przez https. Zaktualizuję pytanie: –

+0

Spróbuj tego: https://stackoverflow.com/a/38598593/2301721 – ashishdhiman2007

Odpowiedz

5

Spróbuj poniżej kodu: -

 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

Po prostu wypróbowałem to, chociaż używałem HttpGet i nadal się zdarza –

+0

Ale to jest dla mnie wrk –

+4

Cool. Mam aplikacje, które działają również za pośrednictwem protokołu HTTPS, ale nie tym razem, dlatego właśnie zadaję to pytanie –

4

W moim przypadku wszystko używane do pracy w porządku. Nagle po 2 dniach moje urządzenie nie wyświetliło żadnej strony ani linku do obrazu https.

Po pewnym dochodzeniu okazało się, że Moje ustawienia czasu nie były aktualne na urządzeniu.

Poprawiłem poprawnie ustawienia czasu i zadziałało.

0

Miałem ten wyjątek, gdy użyłem samopodpisanego certyfikatu + adres IP. Po prostu dodaj te linie:

i Twój HttpURLConnection będzie działać. Ta sztuczka nie jest związana z walidacją z CA! Więc jeśli podam zły CA i użyję tej sztuczki, otrzymam kolejny wyjątek. Więc pozostaje gospodarza zaufany

wszelki wypadek zostawię kod do określania własnego CA tutaj:

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

Nie zapomnij użyć fajne buildTypes fabularnych i umieścić różne urzędy do debugowania/release w OZE folderze .

Powiązane problemy