DefaultHttpClient,证书,Https和发布问题!

我的应用程序需要能够发布到https并保留使用cookie创建的会话。 到目前为止,我有几种不同的方法来尝试这个问题,但没有一种方法可行。 目前我正在研究使用DefaultHttpClient,因为它应该自动保留使用cookie创建的会话。 这样可以省去阅读cookie和提交其他post的痛苦。 但是,当我尝试使用我的代码发布时,post失败并出现下面列出的证书错误。

我之前有这个证书错误的另一种方式我试图解决问题,并使其与HttpsURLConnection一起工作,但这不会自动保留带cookie的会话。

有人可以看看我的代码并告诉我我做错了什么,我能做得更好以及需要改变什么才能让它发挥作用。 谢谢!!

我一直试图解决这个问题几天,我知道在哪里。 每次我再往前走一点,我都会被推回去。 有人可以帮助我! =)

//my posting function private static String post(String urlString, List nameValuePairs) throws MalformedURLException, ProtocolException, IOException { DataOutputStream ostream = null; HostnameVerifier hostnameVerifier = org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER; DefaultHttpClient client = new DefaultHttpClient(); SchemeRegistry registry = new SchemeRegistry(); SSLSocketFactory socketFactory = SSLSocketFactory.getSocketFactory(); socketFactory.setHostnameVerifier((X509HostnameVerifier) hostnameVerifier); registry.register(new Scheme("https", socketFactory, 443)); SingleClientConnManager mgr = new SingleClientConnManager(client.getParams(), registry); DefaultHttpClient http = new DefaultHttpClient(mgr, client.getParams()); HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier); HttpPost httppost = new HttpPost(urlString); httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); HttpResponse response = http.execute(httppost); return response.toString(); } 

 //the error 04-12 00:37:43.941: WARN/System.err(284): javax.net.ssl.SSLException: Not trusted server certificate 04-12 00:37:43.961: WARN/System.err(284): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:371) 04-12 00:37:43.961: WARN/System.err(284): at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:92) 04-12 00:37:43.970: WARN/System.err(284): at org.apache.http.conn.ssl.SSLSocketFactory.createSocket(SSLSocketFactory.java:381) 04-12 00:37:43.980: WARN/System.err(284): at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:164) 04-12 00:37:43.980: WARN/System.err(284): at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164) 04-12 00:37:43.992: WARN/System.err(284): at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119) 04-12 00:37:44.000: WARN/System.err(284): at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:348) 04-12 00:37:44.000: WARN/System.err(284): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555) 04-12 00:37:44.000: WARN/System.err(284): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487) 04-12 00:37:44.020: WARN/System.err(284): at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465) 04-12 00:37:44.020: WARN/System.err(284): at cpe495.smartapp.SmartDBHelper.post(SmartDBHelper.java:208) 04-12 00:37:44.030: WARN/System.err(284): at cpe495.smartapp.SmartDBHelper.authenticate(SmartDBHelper.java:105) 04-12 00:37:44.030: WARN/System.err(284): at cpe495.smartapp.DataSender.submitData(DataSender.java:28) 04-12 00:37:44.040: WARN/System.err(284): at cpe495.smartapp.DataSender.sendData(DataSender.java:21) 04-12 00:37:44.051: WARN/System.err(284): at cpe495.smartapp.SmartApp$1.dataReceivedReceived(SmartApp.java:60) 04-12 00:37:44.061: WARN/System.err(284): at cpe495.smartapp.ConnectDevice.fireDataReceivedEvent(ConnectDevice.java:287) 04-12 00:37:44.061: WARN/System.err(284): at cpe495.smartapp.ConnectDevice.run(ConnectDevice.java:254) 04-12 00:37:44.071: WARN/System.err(284): at java.lang.Thread.run(Thread.java:1096) 04-12 00:37:44.071: WARN/System.err(284): Caused by: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: TrustAnchor for CertPath not found. 04-12 00:37:44.090: WARN/System.err(284): at org.apache.harmony.xnet.provider.jsse.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:168) 04-12 00:37:44.100: WARN/System.err(284): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:366) 04-12 00:37:44.110: WARN/System.err(284): ... 17 more 04-12 00:37:44.110: WARN/System.err(284): Caused by: java.security.cert.CertPathValidatorException: TrustAnchor for CertPath not found. 04-12 00:37:44.129: WARN/System.err(284): at org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi.engineValidate(PKIXCertPathValidatorSpi.java:149) 04-12 00:37:44.150: WARN/System.err(284): at java.security.cert.CertPathValidator.validate(CertPathValidator.java:202) 04-12 00:37:44.150: WARN/System.err(284): at org.apache.harmony.xnet.provider.jsse.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:164) 04-12 00:37:44.150: WARN/System.err(284): ... 18 more 

此问题是由于客户端应用程序无法validation从信任锚(根受信任的证书颁发机构)和SSL服务器证书构建证书路径。 因此,此证书不受信任,SSL握手失败。

apache HTTPClient API提供了一个很好的function,可以帮助您。 SSLSocketFactory构造函数可以采用KeyStore参数 ,包含可信证书。

然后你可以:

  1. 使用keytool创建一个KeyStore ,直接包含根CA证书或服务器证书。
  2. 将此密钥库添加到您的应用程序
  3. 使用此KeyStore构建SSLSocketFactory

有关所有技术细节和代码段,您可以阅读Bob Lee 撰写的这篇博客文章: http : //blog.crazybob.org/2010/02/android-trusting-ssl-certificates.html