当前位置: 首页 > 面试题库 >

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

上官淮晨
2023-03-14
问题内容

问题

我想将https请求发送到我自己的服务器上的站点https://10.2.20.20/fido/EzPay/login.php,并从中获取响应并将其保存在例如字符串中。我在互联网上找到了一些示例代码,并尝试针对我的问题对其进行测试,但它们没有帮助。下面,我介绍一些我已经测试过的代码。

代码示例:

我尝试使用此代码,但总是收到相同的异常“无对等证书”,为什么?

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):在组织中。
apache.harmony.xnet.provider.jsse.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:137)03-02
16:58:25.238:W /
System.err(1868):位于org.apache.http.conn.ssl.AbstractVerifier
.verify(AbstractVerifier.java:93)03-02 16:58:25.238:W /
System.err(1868):位于org.apache.http.conn.ssl.SSLSocketFactory.createSocket(SSLSocketFactory.java:381)03-
02 16:58:25.238:W /
System.err(1868):位于org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:165)03-02
16:58:25.250:W /系统。
err(1868):位于org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)03-02
16:58:25.250:W /
System.err(1868):位于org.apache。http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)03-02
16:58:25.250:W /
System.err(1868):位于org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector
.java:360)03-02 16:58:25.250:W /
System.err(1868):位于org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)03-02
16:58 :25.250:W /
System.err(1868):位于org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)03-02
16:58:25.250:W / System.err(1868)
:在org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)03-02
16:58:25.250:W /
System.err(1868):在com.https.test.DownloadImageTask.doInBackground
(Https_testActivity.java:78)03-02 16:58:25.250:W /
System.err(1868):在com.https.test.DownloadImageTask。doInBackground(Https_testActivity.java:1)03-02
16:58:25.250:W / System.err(1868):at 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 android.os.AsyncTask $ SerialExecutor $
1.run(AsyncTask.java:208) 03-02 16:58:25.257:W / System.err(1868):at
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(线程.java:856)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):at
java.util.concurrent.FutureTask.run(FutureTask.java:137)03-02 16:58:25.253:W
/ System.err(1868):at android.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)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):at
java.util.concurrent.FutureTask.run(FutureTask.java:137)03-02 16:58:25.253:W
/ System.err(1868):at android.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)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
android.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)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
android.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)W /
System.err(1868):位于android.os.AsyncTask $ SerialExecutor $
1.run(AsyncTask.java:208)03-02 16:58:25.257:W /
System.err(1868):位于java.util。
parallel.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)03-02
16:58:25.257:W / System.err(1868):at java.util.concurrent.ThreadPoolExecutor
$ Worker.run(ThreadPoolExecutor.java:569)03 -02 16:58:25.257:W /
System.err(1868):at java.lang.Thread.run(Thread.java:856)W /
System.err(1868):位于android.os.AsyncTask $ SerialExecutor $
1.run(AsyncTask.java:208)03-02 16:58:25.257:W /
System.err(1868):位于java.util。
parallel.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)03-02
16:58:25.257:W / System.err(1868):at java.util.concurrent.ThreadPoolExecutor
$ Worker.run(ThreadPoolExecutor.java:569)03 -02 16:58:25.257:W /
System.err(1868):at
java.lang.Thread.run(Thread.java:856)运行(Thread.java:856)运行(Thread.java:856)

我做错了什么以及如何解决此问题。为什么会出现“ 无对等证书异常

谢谢。

已编辑

Windows Server设置。

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

问题答案:

终于我解决了https问题。当我与之抗争时,主要问题在于服务器,尤其是证书。Android仅支持“
BKS”证书,这就是我们无法从服务器获得响应的原因。为了解决这个问题,我阅读了30多篇文章,最后找到了解决方案。

您可以在下面看到我为解决此问题而执行的步骤:

我要做的第一件事是从我们的fidoserver.crt证书生成.bks密钥库文件,为了做到这一点,我已阅读本文,并执行以下操作:

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

keytool-导入-alias tomcat-文件X://KeyStore/fidoserver.crt -keypass密码-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(使用keytool创建密钥库时提供的密码)加载我们的证书。

在这之后,我所有的测试应用程序开始正常工作。现在,我可以向https发送请求并从中获取响应。我已经使用FIDO服务器测试了应用程序,一切正常!我认为星期一我将在EzPay应用程序中进行一些更改,并且它将开始使用https连接。

参考文献

  • 在Apache Tomcat和Android上使用TLS
  • Android应用程序的SSL验证
  • 密钥库
  • Android:信任SSL证书
  • 充气城堡


 类似资料:
  • 问题内容: 我正在尝试做一个简单的HttpGet来读取网页。我在iOS和Android上通过http(而非https)工作。 网址是内部网络IP和自定义端口,因此我可以使用以下路径使用http读取此类内容: 当我尝试使用https时,出现错误。所以我尝试使用此代码: 但这给我一个错误。 我究竟做错了什么?我可以放心地忽略该证书,因为它是一个具有自签名证书的内部网络,但是我无法控制版本,我的应用程序

  • 本文向大家介绍Android okhttp3.0忽略https证书的方法,包括了Android okhttp3.0忽略https证书的方法的使用技巧和注意事项,需要的朋友参考一下 最近公司项目需要,网络协议支持https,之前接触不多,所以这次想总结一下https在android开发中的相关内容 一、https证书 对于https和证书的概念,大家可以自行搜索百度。 证书分两种: 1、花钱向认证机

  • 我最近升级了Inteliij IDEA 2019.2,如果我尝试从IDE中提取Git,我会发现以下错误:无法访问'https://github.xxx.com/app-Hello-USD/DGS.git/“:SSL证书问题:证书链中的自签名证书。 有人能帮我什么选项,我必须启用。 谢谢

  • 如果我尝试清理我的Gradle缓存,清理我的项目缓存, 那么我甚至无法在AS Bumblebee中同步我的项目 AS: Bumblebee|2021.1.1;静态编程语言插件: 211-1.6.10-Relase-923-AS7442.40; Android Gradle插件: 7.0.2; Gradle: 7.0.2; Gradle JDK: version 11.0.14; NDK: from