Android的SSL - 没有同行证书 [英] Android SSL - No Peer Certificate

查看:102
本文介绍了Android的SSL - 没有同行证书的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

每当这个code运行时,我得到一个没有对等证书的错误。

SSL证书的有效期,从Namecheap(PositiveSSL)购买。它已收到了CA的CRT,并打开精美的Andr​​oid浏览器。

HTTP服务器:nginx

code:

公共无效POSTDATA(){ //添加数据 名单<的NameValuePair> namevaluepairs中=新的ArrayList<的NameValuePair>(2); nameValuePairs.add(新BasicNameValuePair(字符串,myfirststring)); 尝试 {    HttpPost后=新HttpPost(新的URI(https://example.com/submit));     post.setEntity(新UrlEn codedFormEntity(namevaluepairs中));     密钥仓库中可信任= KeyStore.getInstance(BKS);     trusted.load(空,.toCharArray());     SSLSocketFactory的SSLF =新的SSLSocketFactory(信任);     sslf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);     SchemeRegistry schemeRegistry =新SchemeRegistry();     schemeRegistry.register(新计划(https开头,SSLF,443));     SingleClientConnManager厘米=新SingleClientConnManager(post.getParams()             schemeRegistry);     HttpClient的客户=新DefaultHttpClient(厘米,post.getParams());     //执行HTTP POST请求     @燮pressWarnings(未使用)     HTT presponse结果= client.execute(后); }赶上(ClientProtocolException E){     // TODO自动生成的catch块     Log.e(TAG,e.getMessage());     Log.e(TAG,e.toString());     e.printStackTrace(); }赶上(IOException异常E){     // TODO自动生成的catch块     Log.e(TAG,e.getMessage());     Log.e(TAG,e.toString());     e.printStackTrace(); }赶上(的URISyntaxException E){         // TODO自动生成的catch块     Log.e(TAG,e.getMessage());     Log.e(TAG,e.toString());     e.printStackTrace();     }赶上(KeyStoreException E){         // TODO自动生成的catch块         Log.e(TAG,e.getMessage());         Log.e(TAG,e.toString());         e.printStackTrace();     }赶上(抛出:NoSuchAlgorithmException E){         // TODO自动生成的catch块         Log.e(TAG,e.getMessage());         Log.e(TAG,e.toString());         e.printStackTrace();     }赶上(CertificateException E){         // TODO自动生成的catch块         e.printStackTrace();         Log.e(TAG,e.toString());         Log.e(TAG,e.getMessage());     }赶上(KeyManagementException E){         // TODO自动生成的catch块         Log.e(TAG,e.getMessage());         Log.e(TAG,e.toString());         e.printStackTrace();     }赶上(UnrecoverableKeyException E){         // TODO自动生成的catch块         Log.e(TAG,e.getMessage());         Log.e(TAG,e.toString());         e.printStackTrace();     } }

亚行logcat

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

解决方案

尽管这个问题已经被接受的答案,我认为是值得的回答,因为我有一个较旧的Andr​​oid设备上运行2.3.3上同样的错误:

  javax.net.ssl​​.SSLPeerUnverifiedException:没有对方的证书
 

在SO读取多个不同的相关问题后,我得出的结论,这种情况可能有两个原因(也许更多):

  • 在不正确的安装中间证书
  • 证书链的顺序不正确

在我的情况下,这是一个不正确的证书顺序。举个例子,我从张贴的证书顺序<一href="http://stackoverflow.com/questions/4115101/apache-httpclient-on-android-producing-certpathvalidatorexception-issuername">this 的问题与用户有见地的答案 BDC 。您可以通过从终端做以下拿到证书顺序:

  OpenSSL的s_client -connect eu.battle.net:443
 

(很明显,你自己的服务器替换eu.battle.net)。在eu.battle.net当时的顺序是这样的:

 证书链
 0 S:/ C = US / ST =加利福尼亚州/ L =埃尔文/ O =暴雪娱乐公司/ CN = * battle.net
   我:/ C = US / O = Thawte的公司/ CN = Thawte的SSL CA
 1秒:/ C = US / O = Thawte的公司/ OU =认证服务部/ OU =(C)2006 Thawte的公司 - 对于授权只使用/ CN = Thawte的主要根CA
   我:/ C = ZA / ST =西开普/ L =开普敦/ O = Thawte的咨询毫升/ OU =认证服务部/ CN = Thawte的premium服务器CA / EMAILADDRESS = premium服务器@ Thawte的。 COM
 2 S / C = US / O = Thawte的公司/ CN = Thawte的SSL CA
   我:/ C = US / O = Thawte的公司/ OU =认证服务部/ OU =(C)2006 Thawte的公司 - 对于授权只使用/ CN = Thawte的主要根CA
 

尽管它应该是:

 证书链
 0 S:/ C = US / ST =加利福尼亚州/ L =埃尔文/ O =暴雪娱乐公司/ CN = * battle.net
   我:/ C = US / O = Thawte的公司/ CN = Thawte的SSL CA
 1秒:/ C = US / O = Thawte的公司/ CN = Thawte的SSL CA
   我:/ C = US / O = Thawte的公司/ OU =认证服务部/ OU =(C)2006 Thawte的公司 - 对于授权只使用/ CN = Thawte的主要根CA
 2 S / C = US / O = Thawte的公司/ OU =认证服务部/ OU =(C)2006 Thawte的公司 - 对于授权只使用/ CN = Thawte的主要根CA
   我:/ C = ZA / ST =西开普/ L =开普敦/ O = Thawte的咨询毫升/ OU =认证服务部/ CN = Thawte的premium服务器CA / EMAILADDRESS = premium服务器@ Thawte的。 COM
 

该规则是,证书的颁发者N链条应与证书的主题为N + 1。

在我发现这个问题是微不足道的改变服务器和事物的证书才能立即开始工作了Android 2.3.3设备上。我想这是很好的,年长的Andr​​oid版本都有点讨厌的有关证书秩序,但它也是一个噩梦,因为较新的Andr​​oid版本会自动重新排列证书。地狱,即使是旧的iPhone 3GS曾与证书坏了。

Whenever this code runs, I get a 'No Peer Certificate' error.

SSL certificate is valid, bought from Namecheap (PositiveSSL). It has the CA crt before it, and opens fine in the Android browser.

HTTP server: nginx

Code:

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)

解决方案

Even though this question has an accepted answer I thought it worthwhile to answer since I got the same error on an older Android device running 2.3.3:

javax.net.ssl.SSLPeerUnverifiedException: No peer certificate

After reading several different related questions on SO I came to the conclusion that this can happen for two (maybe more?) reasons:

  • Improper installation of an intermediate certificate
  • Incorrect ordering of the certificate chain

In my case it was an incorrect ordering of certificates. As an example I'm posting the cert order from this question with the insightful answer from user bdc. You can get the certificate ordering by doing the following from a terminal:

openssl s_client -connect eu.battle.net:443

(obviously replacing eu.battle.net with your own server). In the case of eu.battle.net at that time the order was:

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

While it should have been:

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

The rule is that the issuer of cert "n" in the chain should match the subject of cert "n+1".

Once I found the problem it was trivial to change the cert order on the server and things immediately started working on the Android 2.3.3 device. I guess it's good that older Android versions are a bit pesky about cert order, but it was also a nightmare since newer Android versions reorder the certs automatically. Hell, even an old iPhone 3GS worked with certs out of order.

这篇关于Android的SSL - 没有同行证书的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆