android developer website說了很多關於此。特別是,似乎重要的一段是
未知的證書頒發機構 在這種情況下,出現SSLHandshakeException是因爲你有一個不是由系統信任的CA。這可能是因爲您有來自尚未受Android信任的新CA的證書,或者您的應用在沒有CA的舊版本上運行。更多的時候,CA不是一個公共CA,而是一個由政府,公司或教育機構等組織自己使用的私人CA。 幸運的是,您可以教HttpsURLConnection信任一組特定的CA.該過程可能有點複雜,因此下面是一個示例,它從InputStream中獲取特定的CA,並使用它創建KeyStore,然後使用該KeyStore創建並初始化TrustManager。 TrustManager是系統用來驗證來自服務器的證書的憑證,並且通過使用一個或多個CA從KeyStore創建一個 - 這些將是該TrustManager信任的唯一CA. 給定新的TrustManager,該示例初始化一個新的SSLContext,它提供了一個SSLSocketFactory,您可以使用該SSLSocketFactory來覆蓋HttpsURLConnection中的默認SSLSocketFactory。這樣連接將使用您的CA進行證書驗證。 下面是使用華盛頓大學CA的完整示例:
// Load CAs from an InputStream
// (could be from a resource or ByteArrayInputStream or ...)
CertificateFactory cf = CertificateFactory.getInstance("X.509");
// From https://www.washington.edu/itconnect/security/ca/load-der.crt
InputStream caInput = new BufferedInputStream(new FileInputStream("load- der.crt"));
Certificate ca;
try {
ca = cf.generateCertificate(caInput);
System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());
} finally {
caInput.close();
}
// Create a KeyStore containing our trusted CAs
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
// Create a TrustManager that trusts the CAs in our KeyStore
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
// Create an SSLContext that uses our TrustManager
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, tmf.getTrustManagers(), null);
// Tell the URLConnection to use a SocketFactory from our SSLContext
URL url = new URL("https://certs.cac.washington.edu/CAtest/");
HttpsURLConnection urlConnection =
(HttpsURLConnection)url.openConnection();
urlConnection.setSSLSocketFactory(context.getSocketFactory());
InputStream in = urlConnection.getInputStream();
copyInputStreamToOutputStream(in, System.out);
有了它知道你的CA的定義TrustManager,該系統能夠驗證服務器證書來自一個受信任的發行人。
注意:許多網站描述一個貧窮的替代解決方案是安裝的TrustManager,什麼也不做。如果你這樣做,你可能不會加密你的通信,因爲任何人都可以在公共的Wi-Fi熱點攻擊你的用戶,通過使用DNS技巧來通過他們自己的代理服務器發送你的用戶的流量。攻擊者隨後可以記錄密碼和其他個人數據。這是有效的,因爲攻擊者可以生成一個證書,並且 - 如果沒有TrustManager實際驗證證書來自可信來源 - 您的應用可能正在與任何人交談。所以不要這樣做,甚至暫時不要。您始終可以讓您的應用程序信任服務器證書的頒發者,所以只需要這樣做。
服務器證書由Comodo發佈,Chrome表示它是可信的。 – elty123