2015-11-13 60 views
1

我正在尝试在简单的testapp中实现ssl连接。与Tomcat的Android SSL连接(自签名证书)SSLPeerUnverifiedException

设置: Ubuntu服务器14.04.3使用Tomcat 7 内部网络的IP:192.168.189.42 Tomcat的SSL:Tomcat Tutorial 设备:API23平板VM(Hyper-V的

https://192.168.177.42:8443/ 

SSL证书经由创建时,Visual Studio) IDE:Android Studio中

首先我测试通过的AsyncTask SSL连接到谷歌:

URL url = new URL("https://google.de"); 
URLConnection urlConnection = url.openConnection(); 
InputStream in = urlConnection.getInputStream(); 
in.close(); 

哪些工作正常。

所以我从提取密钥库使用此命令证书:

keytool -export -alias tomcat -file server.cer -keystore .keystore 

我把这个文件到:myproject的/ RES /生/ server.cer

在另一个的AsyncTask我从谷歌使用的sample code开发人员可以创建一个连接:

 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(); 

,如果我尝试执行此代码我得到以下异常:

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。


好的从评论的答案我有一些insightand尝试另一种aproach。 服务器没有FQDN,CN应该等于FQND,这就是为什么它不能在上面的代码中工作。

由于服务器没有FQDN,我搜索了另一种使用IP地址的方法。我发现这个howto并创建了一个没有CN的证书,但使用了替代名称,并且将IP放在那里,还必须将行keystoreType="PKCS12"添加到tomcat的server.xml中,因为我从缺省密钥库更改为PKCS12。

回答

2

SSL证书的默认行为是让客户端验证服务器名称是否与证书中的名称匹配。这有助于防止中间人攻击和服务器欺骗。如果您的服务器没有名称(192.168.x.x),则不能进行验证。对于您的初始申请,您可以关闭此验证。

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

+0

确实,CN与FQDN不匹配。但要正确解决问题,应该使用正确的CN生成新的服务器证书,并且为了更灵活地使用_ ** SAN字段(subjectAltNames)** _也可以使用。 –

+0

即使在真实的网络中,服务器也没有名称是否可以将IP作为名称? – Alcardis

+0

@Alcardis:您可以将IP放入证书,但取决于客户端,它必须位于CN(大多数不是Safari),SAN部分(IE)的dNSName或SAN部分的iPAddress(大多数但不是IE)中。最好把它放在所有这些地方:( –