Android SSL - нет однорангового сертификата - PullRequest
16 голосов
/ 10 января 2012

Всякий раз, когда запускается этот код, я получаю сообщение об ошибке «Нет сертификата одноранговой сети».

Сертификат SSL действителен, приобретен у Namecheap (PositiveSSL).Перед ним стоит CA crt, и он прекрасно открывается в браузере Android.

HTTP-сервер: nginx

Код:

public void postData() {

// Add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);

nameValuePairs.add(new BasicNameValuePair("string", "myfirststring"));

try {

   HttpPost post = new HttpPost(new URI("https://example.com/submit"));
    post.setEntity(new UrlEncodedFormEntity(nameValuePairs));

    KeyStore trusted = KeyStore.getInstance("BKS");
    trusted.load(null, "".toCharArray());
    SSLSocketFactory sslf = new SSLSocketFactory(trusted);
    sslf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

    SchemeRegistry schemeRegistry = new SchemeRegistry();
    schemeRegistry.register(new Scheme ("https", sslf, 443));
    SingleClientConnManager cm = new SingleClientConnManager(post.getParams(),
            schemeRegistry);

    HttpClient client = new DefaultHttpClient(cm, post.getParams());

    // Execute HTTP Post Request
    @SuppressWarnings("unused")
    HttpResponse result = client.execute(post);

} catch (ClientProtocolException e) {
    // TODO Auto-generated catch block
    Log.e(TAG,e.getMessage());
    Log.e(TAG,e.toString());
    e.printStackTrace();
} catch (IOException e) {
    // TODO Auto-generated catch block
    Log.e(TAG,e.getMessage());
    Log.e(TAG,e.toString());
    e.printStackTrace();
} catch (URISyntaxException e) {
        // TODO Auto-generated catch block
    Log.e(TAG,e.getMessage());
    Log.e(TAG,e.toString());
    e.printStackTrace();
    } catch (KeyStoreException e) {
        // TODO Auto-generated catch block
        Log.e(TAG,e.getMessage());
        Log.e(TAG,e.toString());
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        // TODO Auto-generated catch block
        Log.e(TAG,e.getMessage());
        Log.e(TAG,e.toString());
        e.printStackTrace();
    } catch (CertificateException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        Log.e(TAG,e.toString());
        Log.e(TAG,e.getMessage());
    } catch (KeyManagementException e) {
        // TODO Auto-generated catch block
        Log.e(TAG,e.getMessage());
        Log.e(TAG,e.toString());
        e.printStackTrace();
    } catch (UnrecoverableKeyException e) {
        // TODO Auto-generated catch block
        Log.e(TAG,e.getMessage());
        Log.e(TAG,e.toString());
        e.printStackTrace();
    }
}

Adb logcat :

01-10 15:44:34.872: E/myfirstapp(572): No peer certificate
01-10 15:44:34.872: E/myfirstapp(572): javax.net.ssl.SSLPeerUnverifiedException: No peer certificate
01-10 15:44:34.883: W/System.err(572): javax.net.ssl.SSLPeerUnverifiedException: No peer certificate
01-10 15:44:34.883: W/System.err(572):  at org.apache.harmony.xnet.provider.jsse.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:137)
01-10 15:44:34.883: W/System.err(572):  at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:93)
01-10 15:44:34.908: W/System.err(572):  at org.apache.http.conn.ssl.SSLSocketFactory.createSocket(SSLSocketFactory.java:381)
01-10 15:44:34.908: W/System.err(572):  at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:165)
01-10 15:44:34.908: W/System.err(572):  at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
01-10 15:44:34.914: W/System.err(572):  at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
01-10 15:44:34.914: W/System.err(572):  at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
01-10 15:44:34.914: W/System.err(572):  at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
01-10 15:44:34.914: W/System.err(572):  at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
01-10 15:44:34.914: W/System.err(572):  at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
01-10 15:44:34.933: W/System.err(572):  at com.giggsey.myfirstapp.myfirstappIntent.postData(myfirstappIntent.java:126)
01-10 15:44:34.933: W/System.err(572):  at com.giggsey.myfirstapp.myfirstappIntent.onReceive(myfirstappIntent.java:77)
01-10 15:44:34.933: W/System.err(572):  at android.app.ActivityThread.handleReceiver(ActivityThread.java:2118)
01-10 15:44:34.945: W/System.err(572):  at android.app.ActivityThread.access$1500(ActivityThread.java:122)
01-10 15:44:34.945: W/System.err(572):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
01-10 15:44:34.952: W/System.err(572):  at android.os.Handler.dispatchMessage(Handler.java:99)
01-10 15:44:34.952: W/System.err(572):  at android.os.Looper.loop(Looper.java:137)
01-10 15:44:34.962: W/System.err(572):  at android.app.ActivityThread.main(ActivityThread.java:4340)
01-10 15:44:34.962: W/System.err(572):  at java.lang.reflect.Method.invokeNative(Native Method)
01-10 15:44:34.962: W/System.err(572):  at java.lang.reflect.Method.invoke(Method.java:511)
01-10 15:44:34.972: W/System.err(572):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
01-10 15:44:34.972: W/System.err(572):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
01-10 15:44:34.981: W/System.err(572):  at dalvik.system.NativeStart.main(Native Method)

Ответы [ 10 ]

21 голосов
/ 22 мая 2013

Несмотря на то, что этот вопрос имеет приемлемый ответ, я подумал, что стоит ответить, так как я получил ту же ошибку на более старом Android-устройстве, работающем под управлением 2.3.3:

javax.net.ssl.SSLPeerUnverifiedException: No peer certificate

После прочтения нескольких различных связанных вопросов на SOЯ пришел к выводу, что это может произойти по двум (может быть, еще?) Причинам:

  • Неправильная установка промежуточного сертификата
  • Неправильный порядок цепочки сертификатов

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

openssl s_client -connect eu.battle.net:443

(очевидно, заменив eu.battle.net своим собственным сервером).В случае eu.battle.net на тот момент порядок был:

Certificate chain
 0 s:/C=US/ST=California/L=Irvine/O=Blizzard Entertainment, Inc./CN=*.battle.net
   i:/C=US/O=Thawte, Inc./CN=Thawte SSL CA
 1 s:/C=US/O=thawte, Inc./OU=Certification Services Division/OU=(c) 2006 thawte, Inc. - For authorized use only/CN=thawte Primary Root CA
   i:/C=ZA/ST=Western Cape/L=Cape Town/O=Thawte Consulting cc/OU=Certification Services Division/CN=Thawte Premium Server CA/emailAddress=premium-server@thawte.com
 2 s:/C=US/O=Thawte, Inc./CN=Thawte SSL CA
   i:/C=US/O=thawte, Inc./OU=Certification Services Division/OU=(c) 2006 thawte, Inc. - For authorized use only/CN=thawte Primary Root CA

В то время как он должен был быть:

Certificate chain
 0 s:/C=US/ST=California/L=Irvine/O=Blizzard Entertainment, Inc./CN=*.battle.net
   i:/C=US/O=Thawte, Inc./CN=Thawte SSL CA
 1 s:/C=US/O=Thawte, Inc./CN=Thawte SSL CA
   i:/C=US/O=thawte, Inc./OU=Certification Services Division/OU=(c) 2006 thawte, Inc. - For authorized use only/CN=thawte Primary Root CA
 2 s:/C=US/O=thawte, Inc./OU=Certification Services Division/OU=(c) 2006 thawte, Inc. - For authorized use only/CN=thawte Primary Root CA
   i:/C=ZA/ST=Western Cape/L=Cape Town/O=Thawte Consulting cc/OU=Certification Services Division/CN=Thawte Premium Server CA/emailAddress=premium-server@thawte.com

Правило состоит в том, что эмитент сертификата "n"в цепочке должен совпадать с темой сертификата" n + 1 ".

После того, как я обнаружил проблему, было тривиально изменить порядок сертификата на сервере, и все сразу начало работать на устройстве Android 2.3.3.,Я думаю, это хорошо, что старые версии Android немного надоедливы по поводу порядка сертификатов, но это было также кошмаром, так как новые версии Android переупорядочивают сертификаты автоматически.Черт, даже старый iPhone 3GS работал с сертификатами из строя.

3 голосов
/ 23 августа 2012

Этот технический документ может обобщать все, что вам нужно знать, чтобы ваш SSL работал на Android.Исходя из моего недавнего опыта, лучший подход - это получить SSL-сертификат, который нравится Android.

2 голосов
/ 10 января 2012

Если это не проблема сервера, которая, в большинстве случаев, с которой я сталкивался, связана с отсутствием промежуточных сертификатов или неудачной установкой сертификатов.

Попробуйте использовать реестр схемы, как этот:

SchemeRegistry schReg = new SchemeRegistry();
schReg.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
schReg.register(new Scheme("https",SSLSocketFactory.getSocketFactory(), 443));
SingleClientConnManager conMgr = new SingleClientConnManager(params,post.getParams());
1 голос
/ 11 августа 2015

Проверьте системное время. Если время не текущее, это может привести к ошибке.

0 голосов
/ 15 июня 2018

Я только недавно прошел через эту проблему.Проблема была не в цепочечном порядке, но у меня было это раньше.

Проблема заключалась в том, что сервер принимает только сокетные соединения TLS1.2.android 19 и ниже сокет по умолчанию: TLS1 SSLSocket Docs

С помощью Включить TLS 1.2 в Android 4.4 Мне удалось заставить это работатьОписание вопроса сработало для меня.Но, пожалуйста, убедитесь, что у вас есть код ответа в вашем приложении

0 голосов
/ 23 мая 2017

Убедитесь, что вы используете HttpsURLConnection вместо HttpURLConnection.

0 голосов
/ 18 марта 2015

Я попытался исправить это из кода Android, добавив правило «принять все сертификаты». Но все усилия со стороны андроида были бесполезны. Наконец, создание записи CNAME в регистраторе, которая гарантировала, что все запросы направляются на один и тот же IP-адрес, устранило проблему

0 голосов
/ 16 октября 2013

Я удаляю весь персонал Реестра Схем, и "Ошибка сертификации Нет однорангового узла" решается.

т.е.

Я удаляю этот код из моего

SchemeRegistry schReg = new SchemeRegistry();
schReg.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
schReg.register(new Scheme("https",SSLSocketFactory.getSocketFactory(), 443));
SingleClientConnManager conMgr = new SingleClientConnManager(params,post.getParams());

Возможно, вы можете попытаться удалить его из своего.

0 голосов
/ 06 ноября 2012

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

0 голосов
/ 10 января 2012

Поскольку сертификат действителен, вы не должны использовать пользовательскую SchemeRegistry, вы должны просто полагаться на механизм проверки сертификата Android по умолчанию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...