Безопасное исправление: javax.net.ssl.SSLPeerUnverifiedException: нет однорангового сертификата

Есть десятки сообщений об этой проблеме (javax.net.ssl.SSLPeerUnverifiedException: no peer certificate), но я не нашел ничего, что сработает для меня.

Многие сообщения (например, и это ) «решают» это, разрешая принимать все сертификаты, но, конечно, это нехорошее решение для чего угодно, кроме тестирования.

Другие кажутся довольно локализованными и не работают для меня. Я очень надеюсь, что у кого-то есть понимание, которого мне не хватает.

Итак, моя проблема: я тестирую на сервере, доступном только через локальную сеть, подключаясь через HTTPS. Выполнение вызова, которое мне нужно через браузер, отлично работает. Не жалуйтесь на сертификаты, и если вы проверяете сертификаты, все выглядит хорошо.

Когда я пытаюсь на своем устройстве Android, я получаю javax.net.ssl.SSLPeerUnverifiedException: No peer certificate

Вот код, который его вызывает:

 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 

Мой код для 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; } 

Любая помощь приветствуется.

редактировать

Также просто упомянуть, что у меня были другие проблемы с SSL с другим приложением, но добавление части SchemeRegistry исправило это для меня раньше.

Изменить 2

Пока я тестировал только на Android 3.1, но мне нужно, чтобы это работало на Android 2.2+ независимо. Я только что протестировал в браузере на вкладке Android (Android 3.1), и он жалуется на сертификат. Это нормально в моем браузере ПК, но не в браузере Android или в моем приложении.

Редактировать 3

Оказывается, браузер iOS также жалуется на это. Я начинаю думать, что проблема с цепочкой сертификатов описана здесь ( сертификат SSL не доверен – только на мобильных устройствах )

Solutions Collecting From Web of "Безопасное исправление: javax.net.ssl.SSLPeerUnverifiedException: нет однорангового сертификата"

Оказывается, мой код был в порядке, и проблема заключалась в том, что сервер не возвращал полную цепочку сертификатов. Для получения дополнительной информации см. Этот пост SO и этот пост суперпользователя:

Сертификат SSL не доверяется – только на мобильных устройствах

https://superuser.com/questions/347588/how-do-ssl-chains-work

Попробуйте под кодом: –

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

В моем случае все хорошо работало. Неожиданно через 2 дня мое устройство не показывало ни одного сайта https или ссылки на изображение.

После некоторого расследования выясняется, что настройки My time не были обновлены на устройстве.

Я правильно изменил настройки времени, и это сработало.