将其插入"javax.net.ssl.SSLPeerUnverifiedException: No peer certificate error"运行Android 2.3的模拟器中,而不是在4中运行。在4中,它可以完美运行。我正在尝试通过https连接到实时服务器。它使用有效的Thawte证书,在所有浏览器以及Android 3和4中均可正常运行。
"javax.net.ssl.SSLPeerUnverifiedException: No peer certificate error"
如果有人有代码帮助,请谢谢。另外,如果有人对安全解决方法有任何建议,我将不胜感激。我仍在学习,并且已经在这个问题上解决了一个星期。它必须结束,所以我可以继续工作和学习。嗯
这是HttpCLient代码,由Antoine Hauck提供(http://blog.antoine.li/2010/10/22/android-trusting-ssl-certificates/):
import java.io.InputStream; import java.security.KeyStore; import java.security.cert.CertificateException; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import javax.security.cert.X509Certificate; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.conn.scheme.PlainSocketFactory; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.scheme.SchemeRegistry; import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.conn.SingleClientConnManager; import android.content.Context; public class MyHttpClient extends DefaultHttpClient { final Context context; public MyHttpClient(Context context) { this.context = context; } @Override protected ClientConnectionManager createClientConnectionManager() { SchemeRegistry registry = new SchemeRegistry(); registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); // Register for port 443 our SSLSocketFactory with our keystore // to the ConnectionManager registry.register(new Scheme("https", newSslSocketFactory(), 443)); return new SingleClientConnManager(getParams(), registry); } private SSLSocketFactory newSslSocketFactory() { try { // Get an instance of the Bouncy Castle KeyStore format KeyStore trusted = KeyStore.getInstance("BKS"); // Get the raw resource, which contains the keystore with // your trusted certificates (root and any intermediate certs) InputStream in = context.getResources().openRawResource(R.raw.my_cert); try { // Initialize the keystore with the provided trusted certificates // Also provide the password of the keystore trusted.load(in, "my_pass".toCharArray()); } finally { in.close(); } // Pass the keystore to the SSLSocketFactory. The factory is responsible // for the verification of the server certificate. SSLSocketFactory sf = new SSLSocketFactory(trusted); // Hostname verification from certificate // http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html#d4e506 sf.setHostnameVerifier(SSLSocketFactory.STRICT_HOSTNAME_VERIFIER); return sf; } catch (Exception e) { throw new AssertionError(e); } } }
这是实例化它的代码:
DefaultHttpClient client = new MyHttpClient(getApplicationContext()); HttpPost post = new HttpPost(server_login_url); List <NameValuePair> parameters = new ArrayList <NameValuePair>(); parameters.add(new BasicNameValuePair("username", user)); parameters.add(new BasicNameValuePair("password", pass)); try { post.setEntity(new UrlEncodedFormEntity(parameters, HTTP.UTF_8)); } catch (UnsupportedEncodingException e2) { // TODO Auto-generated catch block Log.d(DEBUG_TAG, "in UnsupportedEncodingException - " + e2.getMessage()); e2.printStackTrace(); } // Execute the GET call and obtain the response HttpResponse getResponse = null; try { getResponse = client.execute(post); } catch (ClientProtocolException e) { // TODO Auto-generated catch block // Toast.makeText(getBaseContext(),message,Toast.LENGTH_LONG).show(); Log.d(DEBUG_TAG, "in ClientProtocolException - " + e.getMessage()); } catch (IOException e) { // TODO Auto-generated catch block // Toast.makeText(getBaseContext(),message,Toast.LENGTH_LONG).show(); Log.d(DEBUG_TAG, "in client.execute IOException - " + e.getMessage()); e.printStackTrace(); }
该错误被捕获在IOException块中。这是堆栈:
javax.net.ssl.SSLPeerUnverifiedException: No peer certificate org.apache.harmony.xnet.provider.jsse.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:258) org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:93) org.apache.http.conn.ssl.SSLSocketFactory.createSocket(SSLSocketFactory.java:381) org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:164) org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164) org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119) org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:359) org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555) org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487) org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465) org.ffb.tools.SplashActivity$LoginTask.makeConnection(SplashActivity.java:506) org.ffb.tools.SplashActivity$LoginTask.doLogin(SplashActivity.java:451) org.ffb.tools.SplashActivity$LoginTask.doInBackground(SplashActivity.java:439) org.ffb.tools.SplashActivity$LoginTask.doInBackground(SplashActivity.java:1) android.os.AsyncTask$2.call(AsyncTask.java:185) java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306) java.util.concurrent.FutureTask.run(FutureTask.java:138) java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088) java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581) java.lang.Thread.run(Thread.java:1019)
这是链顺序(来自openssl命令):
我认为这条链看起来不错。
i:/C=US/O=Thawte, Inc./OU=Domain Validated SSL/CN=Thawte DV SSL CA 1 s:/C=US/O=Thawte, Inc./OU=Domain Validated SSL/CN=Thawte DV 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
当我调试类似问题时,此线程确实很有帮助。
摘要Android 2.3 HTTPS / SSL清单:
您在服务器上是否安装了证书链,订购顺序正确吗?大多数浏览器会处理乱码证书链,但Android 2.3不会。上面提到的线程中bdc的答案描述了如何使用“ openssl s_client -connect yourserver.com:443”来检查SSL证书和链的有效性。
挖掘底部抽屉中的旧2.3设备时,请确保在停电时间过长后正确设置日期和时间。