java - DefaultHttpClient、证书、Https 和发布问题!

标签 java android post https certificate

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

我之前用另一种方法遇到了这个证书错误,我试图解决这个问题并让它与 HttpsURLConnection 一起工作,但这不会自动保留与 cookie 的 session 。

有人可以看看我的代码并告诉我我做错了什么,我可以做得更好以及需要更改什么才能使其正常工作。?谢谢!!

几天来我一直在尝试解决这个问题,现在我知道在哪里了。每次我走得更远,我都会被推得更远。有人可以帮助我吗! =)

//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

最佳答案

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

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

然后你可以:

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

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

关于java - DefaultHttpClient、证书、Https 和发布问题!,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5629122/

相关文章:

java - 正则表达式在不在括号内的点上拆分字符串

java - 如何使用 ORACLE SQLLDR 执行自定义 SQL 命令

java - 还有什么允许的特殊 java 方法名称?

PHP POST 和 GET 在同一个语句中

json - 如何在不重复代码的情况下填充 JSON 对象的一部分?

c# - 自定义 http 服务可以很好地响应本地 IP 地址,但不能响应 localhost 或 127.0.0.1

java - 监视 HPSM 9.20 Web 服务中的新事件或更新事件

android - dagger 2 viewmodels 和 ViewModelProvider.Factory

java - 存储临时 QuestionID-AnswerID 数据的最佳方式

android - 无法以编程方式重现布局