https(无对等证书)在android中的问题

问题

我想发送https请求到站点https://10.2.20.20/fido/EzPay/login.php我自己的服务器,并得到它的响应,并保存在一个string。 我在网上find了一些示例代码,并尝试testing他们的问题,但他们没有帮助。 下面我介绍一些我testing过的代码部分。


代码示例:

我尝试这个代码,但我总是得到同样的exception“没有同行证书”为什么?

try { 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 httpClient = new DefaultHttpClient(mgr, client.getParams()); // Set verifier HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier); // Example send http request final String url = "https://10.2.20.20/fido/EzPay/login.php"; HttpPost httpPost = new HttpPost(url); HttpResponse response = httpClient.execute(httpPost); BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); String line = ""; while ((line = rd.readLine()) != null) { Log.i(DownloadImageTask.class.getName(), line); } } catch(IOException ex) { Log.e(DownloadImageTask.class.getName(), ex.getMessage()); } 

例外。

03-02 16:58:25.234:W / System.err(1868):javax.net.ssl.SSLPeerUnverifiedException:没有同级证书03-02 16:58:25.238:W / System.err(1868):at org。 apache.harmony.xnet.provider.jsse.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:137)03-02 16:58:25.238:W / System.err(1868):at org.apache.http.conn.ssl.AbstractVerifier .verify(AbstractVerifier.java:93)03-02 16:58:25.238:W / System.err(1868):at org.apache.http.conn.ssl.SSLSocketFactory.createSocket(SSLSocketFactory.java:381)03- 02 16:58:25.238:W / System.err(1868):at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:165)03-02 16:58:25.250:W / System。 err(1868):at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)03-02 16:58:25.250:W / System.err(1868):at org.apache.http .impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)03-02 16:58:25.250:W / System.err(1868):at org.apache.http.impl.client.DefaultRequestDirector.execut e(DefaultRequestDirector.java:360)03-02 16:58:25.250:W / System.err(1868):at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)03-02 16:58:25.250:W / System.err(1868):at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)03-02 16:58:25.250:W / System.err (1868):at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)03-02 16:58:25.250:W / System.err(1868):at com.https.test。 DownloadImageTask.doInBackground(Https_testActivity.java:78)03-02 16:58:25.250:W / System.err(1868):at com.https.test.DownloadImageTask.doInBackground(Https_testActivity.java:1)03-02 16: 58:25.250:W / System.err(1868):在android.os.AsyncTask $ 2.call(AsyncTask.java:264)03-02 16:58:25.253:W / System.err(1868):在java。 util.concurrent.FutureTask $ Sync.innerRun(FutureTask.java:305)03-02 16:58:25.253:W / System.err(1868):在java.util.concurrent.FutureTask.run(FutureTask.java:137 )03-02 16:58:25.253:W / System.err(1868):at和 roid.os.AsyncTask $ SerialExecutor $ 1.run(AsyncTask.java:208)03-02 16:58:25.257:W / System.err(1868):在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java: 1076)03-02 16:58:25.257:W / System.err(1868):在java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:569)03-02 16:58:25.257:W / System.err(1868):在java.lang.Thread.run(Thread.java:856)


我做错了什么,我怎么能解决这个问题。 为什么我得到“ 没有同行证书 ”exception?

谢谢。

编辑


Windows服务器设置。

 <VirtualHost *:443> ServerName 10.2.20.20 Alias /fido/EzPay/ "d:/fido/EzPay/" Alias /fido/EzPay "d:/fido/EzPay/" <Directory "d:/fido/EzPay/"> Options Indexes FollowSymLinks MultiViews AllowOverride all Order allow,deny Allow from all </Directory> # These are the actual SSL directives needed to get it all working! SSLEngine on SSLCertificateFile C:/wamp/bin/apache/apache2.2.17/conf/ssl/fidoserver.crt SSLCertificateKeyFile C:/wamp/bin/apache/apache2.2.17/conf/ssl/fidoserver.pem </VirtualHost> 

Solutions Collecting From Web of "https(无对等证书)在android中的问题"

最后我解决了https问题。 当我打的主要问题是在服务器,具体在证书。 Android仅支持“BKS”证书,这是我们无法从服务器获得响应的原因。 为了解决这个问题,我已经阅读了30多篇文章,最后find了解决办法。

我所做的解决这个问题的步骤你可以在下面看到:

我做的第一件事就是从我们的fidoserver.crt证书生成.bks密钥库文件,为了做到这一点,我已经阅读了这篇文章,并做了以下工作:

  1. 打开cmd
  2. 转到JDK文件夹“cd X:\ Programs \ Java \ Jdk6 \ bin”
  3. 拨打以下命令:

keytool -import -alias tomcat -file X://KeyStore/fidoserver.crt -keypass password -keystore X://KeyStore/keystore.bks -storetype BKS -storepass 222222 -providerClass org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath X://KeyStore/bcprov-jdk16-146.jar

在运行这个命令之前,我已经下载了Bouncy Castle .jar文件,并把它放在带有证书的文件夹中。 在完成这一步之后,我得到了keystore.bks文件,它是Android应用程序的正确证书文件。 我把这个文件放在Android的mnc / sdcard文件夹中。 在java代码中,我写下面的代码来读取keystore.bbk文件

 KeyStore trustStore = KeyStore.getInstance( "BKS" /*KeyStore.getDefaultType()*/ ); FileInputStream instream = new FileInputStream(new File("/mnt/sdcard/keystore.bks")); try { trustStore.load(instream, "222222".toCharArray()); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (CertificateException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { instream.close(); } catch (Exception ignore) {} } // Create socket factory with given keystore. SSLSocketFactory socketFactory = new SSLSocketFactory(trustStore); SSLSocketFactory socketFactory = new SSLSocketFactory(trustStore); Scheme sch = new Scheme("https", socketFactory, 443); httpclient.getConnectionManager().getSchemeRegistry().register(sch); HttpGet httpget = new HttpGet("https://10.2.20.20/fido/EzPay/login.php"); System.out.println("executing request " + httpget.getRequestLine()); HttpResponse response = httpclient.execute(httpget); HttpEntity entity = response.getEntity(); System.out.println("----------------------------------------"); System.out.println(response.getStatusLine()); if (entity != null) { System.out.println("Response content length: " + entity.getContentLength()); } // Print html. BufferedReader in = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); String line = ""; while ((line = in.readLine()) != null) { System.out.println(line); } in.close(); 

这一切都允许m加载我们的证书与给定的密码222222(密码,我们给与密钥库创build密钥存储时)。

在此之后,我所有的testing应用程序开始正常工作。 现在我可以发送请求到https并从中获得响应。 我已经用FIDO服务器testing了应用程序,一切都很好! 我想星期一我会在EzPay应用程序中进行一些更改,它将开始使用https连接。

参考

  • 在Apache Tomcat和Android上使用TLS
  • Android应用程序的SSLvalidation
  • 密钥库
  • Android:信任SSL证书
  • 充气城堡
  • Android / Java – 如何创buildHTTPS连接?

请求方法POST不适合URL / 。 我们知道的就这些。

示例1不起作用,因为您似乎不允许向该页面发送POST请求。 尝试:

 /* ... */ HttpGet httpGet = new HttpGet(url); HttpResponse response = httpClient.execute(httpGet); /* ... */ 

示例2不起作用,因为您不接受网站证书作为接受的证书,所以它也应该是这样的:

 /* ... */ HostnameVerifier hostnameVerifier = org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER; 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 httpClient = new DefaultHttpClient(mgr, client.getParams()); /* ... */ 

你有没有试过用浏览器打开页面? 如果它不打开你的configuration是错误的。

请注意,如果您使用自签名证书,则可能会遇到一些连接问题。 一些Android内核版本(在2.6.32.9之前)不喜欢自我certificate的证书。