首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >到Tomcat (自签名证书) SSLPeerUnverifiedException的Android连接

到Tomcat (自签名证书) SSLPeerUnverifiedException的Android连接
EN

Stack Overflow用户
提问于 2015-11-13 18:16:17
回答 1查看 612关注 0票数 1

我目前正试图在一个简单的testapp中实现ssl连接。

安装程序:UbuntuServer14.04.3与Tomcat 7内部网络IP: 192.168.189.42 Tomcat SSL:

代码语言:javascript
复制
https://192.168.177.42:8443/

通过:Tomcat教程设备创建的SSL证书: API23 Tablet VM (Hyper-V,Visual ) IDE: Android

首先,我通过AsyncTask测试了与谷歌的ssl连接:

代码语言:javascript
复制
URL url = new URL("https://google.de");
URLConnection urlConnection = url.openConnection();
InputStream in = urlConnection.getInputStream();
in.close();

效果很好。

因此,我使用以下命令从keystore提取证书:

代码语言:javascript
复制
keytool -export -alias tomcat -file server.cer -keystore .keystore

我将该文件放入: myproject/res/raw/server.cer

在另一个AsyncTask中,我使用谷歌开发人员的样本代码创建了一个连接:

代码语言:javascript
复制
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        InputStream caInput = new BufferedInputStream(context.getResources().openRawResource(R.raw.server));
        Certificate ca;

        ca = cf.generateCertificate(caInput);

        Log.d("CERT: ", "ca=" + ((X509Certificate) ca).getSubjectDN());

        caInput.close();

        String keyStoreType = KeyStore.getDefaultType();
        KeyStore keyStore = KeyStore.getInstance(keyStoreType);
        keyStore.load(null, null);
        keyStore.setCertificateEntry("ca", ca);

        String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
        tmf.init(keyStore);

        SSLContext context = SSLContext.getInstance("TLS");
        context.init(null, tmf.getTrustManagers(), null);

        URL url = new URL("https://192.168.177.42:8443/");
        HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
        urlConnection.setSSLSocketFactory(context.getSocketFactory());
        InputStream in = urlConnection.getInputStream();
        in.close();

如果我试图执行这段代码,就会得到以下异常:

代码语言:javascript
复制
11-13 18:39:02.508  12135-12280/moe.testapp W/System.err﹕ javax.net.ssl.SSLPeerUnverifiedException: Hostname 192.168.177.42 not verified:
11-13 18:39:02.508  12135-12280/moe.testapp W/System.err﹕ certificate: sha1/wFJI0CzwVvJ2MuGvpoJaFO8y4z8=
11-13 18:39:02.508  12135-12280/moe.testapp W/System.err﹕ DN: CN=Alcardis,OU=AL,O=AL,L=test,ST=state,C=XX
11-13 18:39:02.508  12135-12280/moe.testapp W/System.err﹕ subjectAltNames: []
11-13 18:39:02.509  12135-12280/moe.testapp W/System.err﹕ at com.android.okhttp.internal.http.SocketConnector.connectTls(SocketConnector.java:120)
11-13 18:39:02.509  12135-12280/moe.testapp W/System.err﹕ at com.android.okhttp.Connection.connect(Connection.java:143)
11-13 18:39:02.509  12135-12280/moe.testapp W/System.err﹕ at com.android.okhttp.Connection.connectAndSetOwner(Connection.java:185)
11-13 18:39:02.509  12135-12280/moe.testapp W/System.err﹕ at com.android.okhttp.OkHttpClient$1.connectAndSetOwner(OkHttpClient.java:128)
11-13 18:39:02.509  12135-12280/moe.testapp W/System.err﹕ at com.android.okhttp.internal.http.HttpEngine.nextConnection(HttpEngine.java:341)
11-13 18:39:02.509  12135-12280/moe.testapp W/System.err﹕ at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:330)
11-13 18:39:02.509  12135-12280/moe.testapp W/System.err﹕ at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:248)
11-13 18:39:02.509  12135-12280/moe.testapp W/System.err﹕ at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:433)
11-13 18:39:02.509  12135-12280/moe.testapp W/System.err﹕ at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:384)
11-13 18:39:02.509  12135-12280/moe.testapp W/System.err﹕ at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:231)
11-13 18:39:02.509  12135-12280/moe.testapp W/System.err﹕ at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getInputStream(DelegatingHttpsURLConnection.java:210)
11-13 18:39:02.509  12135-12280/moe.testapp W/System.err﹕ at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java)
11-13 18:39:02.509  12135-12280/moe.testapp W/System.err﹕ at moe.testapp.TomcatWebservice.doInBackground(TomcatWebservice.java:64)
11-13 18:39:02.509  12135-12280/moe.testapp W/System.err﹕ at moe.testapp.TomcatWebservice.doInBackground(TomcatWebservice.java:28)
11-13 18:39:02.509  12135-12280/moe.testapp W/System.err﹕ at android.os.AsyncTask$2.call(AsyncTask.java:295)
11-13 18:39:02.509  12135-12280/moe.testapp W/System.err﹕ at java.util.concurrent.FutureTask.run(FutureTask.java:237)
11-13 18:39:02.509  12135-12280/moe.testapp W/System.err﹕ at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
11-13 18:39:02.509  12135-12280/moe.testapp W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
11-13 18:39:02.509  12135-12280/moe.testapp W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
11-13 18:39:02.509  12135-12280/moe.testapp W/System.err﹕ at java.lang.Thread.run(Thread.java:818)

我不明白为什么主机不能被验证。证书被正确读取(我至少可以在调试器中以正确的值访问它),android应用程序也可以通过标准web浏览器中的https访问tomcat。

好的,从答案和评论,我得到了一些洞察力,并尝试了另一个。服务器没有FQDN,CN应该等于FQND,这就是为什么它不能在上面的代码中工作。

因为服务器没有FQDN,所以我搜索了另一种使用ip地址的方法。我找到了这个何图,创建了一个没有CN的证书,但是使用了alternativ名称,并将ip放入其中,我还必须将行keystoreType="PKCS12"添加到tomcat的server.xml中,因为我从默认的keystore更改为PKCS12。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-11-13 18:29:58

SSL证书的默认行为是客户端验证服务器名称是否与证书中的服务器名称匹配。这有助于防止中间人攻击和服务器欺骗。当您的服务器没有名称(192.168.x.x)时,就无法进行验证。对于初始应用程序,可以关闭此验证。

对于任何实际应用程序,您都应该保留服务器名称验证。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33699312

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档