DefaultHttpClient、证书、Https 和发布问题!
我的应用程序需要能够发布到 https 并保留使用 cookie 创建的会话。到目前为止,我有几种不同的方法来尝试这个问题,但没有一个有效。目前我正在考虑使用 DefaultHttpClient,因为它应该自动保留使用 cookie 创建的会话。这让我免去了阅读 cookie 并与其他帖子一起提交的痛苦。但是,当我尝试使用我拥有的代码发布时,发布失败并出现下面列出的证书错误。
我之前遇到过此证书错误,我尝试通过另一种方式解决问题并使其与 HttpsURLConnection 一起使用,但这不会自动保留带有 cookie 的会话。
有人可以看一下我的代码并告诉我我做错了什么,我可以做得更好以及需要更改哪些内容才能使其正常工作。?谢谢!!
几天来我一直在尝试解决这个问题,并且我知道在哪里。每次我走得更远,我就会被推得更远。有人可以帮助我吗! =)
//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
My application needs to be able to post to https and preserve the session that is created with cookies. So far, i have several different ways of trying the problem and none are working. Currently i am looking into using DefaultHttpClient because it is supposed to automatically preserve sessions created with cookies. This saves me the pain of reading the cookie and submitting with every other post. However, when i try to post using the code i have, the post fails with a certificate error that is listed below.
I had this certificate error earlier with another way i was trying to solve the problem and got it working with HttpsURLConnection, but that does not preserve sessions with cookies automatically.
Can someone please take a look at my code and tell me what i am doing wrong, what i can do better and what needs to change to get it to work.? THANKS!!
I have been trying to solve this problem for a few days now and i am getting know where. Every time i get a little further i get pushed further back. Can someone please assist me! =)
//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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
此问题是由于客户端应用程序无法验证从信任锚(根受信任的证书颁发机构)和 SSL 服务器证书构建的证书路径。因此,该证书不受信任,SSL 握手失败。
apache HTTPClient API 提供了一个很好的功能可以帮助您。
SSLSocketFactory
构造函数可以采用KeyStore
参数,包含可信证书。然后您可以:
keytool
创建一个包含根 CA 证书或直接包含服务器证书的KeyStore
。KeyStore
构建 SSLSocketFactory有关所有技术详细信息和代码片段,您可以阅读 Bob Lee 的这篇博客文章:http://blog.crazybob.org/2010/02/android-trusting-ssl-certificates.html
This issue is due to the fact that the client application is not able to validate build a certificate path from a trust anchor (a root trusted certification authority) and the SSL server certificate. Therefore this certificate is not trusted and the SSL handshake fails.
The apache HTTPClient API provides a nice feature which could help you. The
SSLSocketFactory
constructor can take aKeyStore
parameter, contains the trusted certificates.Then you can:
KeyStore
withkeytool
containing either the root CA certificate or the server certificate directly.KeyStore
For all technical details and code snippets you can read this blog post from Bob Lee: http://blog.crazybob.org/2010/02/android-trusting-ssl-certificates.html