我正在嘗試在簡單的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。
確實,CN與FQDN不匹配。但要正確解決問題,應該使用正確的CN生成新的服務器證書,並且爲了更靈活地使用_ ** SAN字段(subjectAltNames)** _也可以使用。 –
即使在真實的網絡中,服務器也沒有名稱是否可以將IP作爲名稱? – Alcardis
@Alcardis:您可以將IP放入證書,但取決於客戶端,它必須位於CN(大多數不是Safari),SAN部分(IE)的dNSName或SAN部分的iPAddress(大多數但不是IE)中。最好把它放在所有這些地方:( –