2011-04-12 72 views
2

我的应用程序需要能够发布到https并保留使用cookie创建的会话。到目前为止,我有几种不同的方式来解决这个问题,而且没有任何工作。目前我正在研究使用DefaultHttpClient,因为它应该自动保留使用Cookie创建的会话。这为我节省了阅读cookie并与其他每个帖子一起提交的痛苦。但是,当我尝试使用我拥有的代码进行发布时,发布失败,并显示下面列出的证书错误。DefaultHttpClient,证书,https和发布问题!

我以前用另一种方式尝试解决问题并使用HttpsURLConnection工作时发现了此证书错误,但这不会自动保留会话。

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

我一直试图解决这个问题几天,现在我知道在哪里。每当我进一步得到进一步推进。有人可以帮助我! =)

//my posting function 
    private static String post(String urlString, List<NameValuePair> 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 

回答

2

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

apache HTTPClient API提供了一个很好的功能,可以帮助你。 SSLSocketFactory构造函数can take a KeyStore parameter包含可信证书。

然后,您可以:

  1. 创建一个KeyStore含有两种根CA证书或直接在服务器证书keytool
  2. 这个密钥库添加到应用程序
  3. 构建的SSLSocketFactory这个KeyStore

对于所有的技术细节和代码片段,你可以阅读从鲍勃·李这篇博客文章:http://blog.crazybob.org/2010/02/android-trusting-ssl-certificates.html

+0

,只要我得到我会尝试这个解决方案的机会。我之前已经尝试过一次,但没有奏效。不过,自那以后我做了一些改变,并会再次尝试。谢谢 – prolink007 2011-04-15 15:03:29

+0

如果服务器不发送中间CA证书,也会发生此错误。在这种情况下,应用程序无法将证书链附加到信任锚点。 – Jcs 2011-04-16 10:11:36

+0

我遵循上面的三个步骤,有时它可以工作,但更多的时候不会。你有什么解释吗?有没有办法绕过它,因为它不是我的服务器。 – Diego 2013-07-31 23:35:48