android使用https和ssl

在android app端訪問(wèn)https服務(wù)時(shí),搜到的資料大都是自簽名證書(shū)認(rèn)證的邏輯。想辦法扒到了Google官方的資料看了一下,豁然開(kāi)朗。

基礎(chǔ)概念就不解釋了,只說(shuō)使用方法。

使用CA簽署的證書(shū)

如果服務(wù)端使用的是知名CA機(jī)構(gòu)簽名的證書(shū),android連接https的代碼非常簡(jiǎn)單:

URL url = new URL("https://wikipedia.org");
URLConnection urlConnection = url.openConnection();
InputStream in = urlConnection.getInputStream();
copyInputStreamToOutputStream(in, System.out);

常見(jiàn)問(wèn)題

如果在鏈接https時(shí)遇到錯(cuò)誤:

javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
        at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:374)
        at libcore.net.http.HttpConnection.setupSecureSocket(HttpConnection.java:209)
        at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:478)
        at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:433)
        at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:290)
        at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:240)
        at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:282)
        at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:177)
        at libcore.net.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:271)

可能有以下幾個(gè)原因:
1.簽名證書(shū)的CA機(jī)構(gòu)不知名
2.使用了自簽名的證書(shū)
3.服務(wù)端配置問(wèn)題

解決方案

1.導(dǎo)致SSLHandshakeException是由于簽署證書(shū)的CA不被系統(tǒng)所信任。一種原因是CA機(jī)構(gòu)比較新,還沒(méi)被android系統(tǒng)證書(shū)庫(kù)內(nèi)置?;蛘吣愕腶ndroid版本比較舊,證書(shū)庫(kù)不全。
這種情況的解決方案和使用了自簽名證書(shū)的方案是一樣的,重寫(xiě)Google默認(rèn)的證書(shū)校驗(yàn)邏輯。

// 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 CAsString 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 SSLContextURL 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);

2.服務(wù)器配置問(wèn)題
修改服務(wù)器配置或者使用上面的解決方案,直接信任該證書(shū)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容