Android端關於HTTPS的認證---->可用
1.關於HTTPS
HTTPS(全稱:Hyper Text Transfer Protocol over Secure Socket Layer),是以安全為目標的HTTP通道,簡單講是HTTP的安全版。即HTTP下加入SSL層,HTTPS的安全基礎是SSL,因此加密的詳細內容就需要SSL。 它是一個URI scheme(抽象識別符號體系),句法類同http:體系。用於安全的HTTP資料傳輸。https:URL表明它使用了HTTP,但HTTPS存在不同於HTTP的預設埠及一個加密/身份驗證層(在HTTP與TCP之間)。
2.普通的HTTP post請求
public void requestPost當請求的介面地址變為HTTPS型別的話,會丟擲如下異常(Map<String , String> params){ HttpURLConnection httpURLConnection = null; String result = null; try { //合成引數 byte [] requestParams = generateParams(params); URL url = new URL(requestUrl); httpURLConnection = (HttpURLConnection) url.openConnection(); httpURLConnection.setConnectTimeout(60*1000); httpURLConnection.setReadTimeout(60*1000); httpURLConnection.setDoOutput(true); httpURLConnection.setDoInput(true); httpURLConnection.setUseCaches(false); httpURLConnection.setRequestMethod("POST"); httpURLConnection.setInstanceFollowRedirects(true); httpURLConnection.connect(); DataOutputStream dos = newDataOutputStream(httpURLConnection.getOutputStream()); dos.write(requestParams); dos.flush(); dos.close(); if (httpURLConnection.getResponseCode() == HttpURLConnection.HTTP_OK){ result = stream2string(httpURLConnection.getInputStream()); }else { Log.e(TAG, "requestPost: 請求失敗--->"+httpURLConnection.getResponseCode()); } httpURLConnection.disconnect(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
12-17 14:08:38.590 18126-18188/? W/System.err: javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
12-17 14:08:38.590 18126-18188/? W/System.err: at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:357)
12-17 14:08:38.590 18126-18188/? W/System.err: at com.android.okhttp.internal.http.SocketConnector.connectTls(SocketConnector.java:212)
12-17 14:08:38.590 18126-18188/? W/System.err: at com.android.okhttp.Connection.connect(Connection.java:1322)
12-17 14:08:38.590 18126-18188/? W/System.err: at com.android.okhttp.Connection.connectAndSetOwner(Connection.java:1410)
12-17 14:08:38.590 18126-18188/? W/System.err: at com.android.okhttp.OkHttpClient$1.connectAndSetOwner(OkHttpClient.java:131)
12-17 14:08:38.590 18126-18188/? W/System.err: at com.android.okhttp.internal.http.HttpEngine.nextConnection(HttpEngine.java:484)
12-17 14:08:38.590 18126-18188/? W/System.err: at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:465)
12-17 14:08:38.590 18126-18188/? W/System.err: at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:371)
12-17 14:08:38.590 18126-18188/? W/System.err: at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:476)
12-17 14:08:38.590 18126-18188/? W/System.err: at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:118)
12-17 14:08:38.590 18126-18188/? W/System.err: at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.connect(DelegatingHttpsURLConnection.java:89)
12-17 14:08:38.590 18126-18188/? W/System.err: at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:25)
12-17 14:08:38.590 18126-18188/? W/System.err: at com.binguokeji.sdk.library.SimpleNetHelper.post(***.java:232)
12-17 14:08:38.590 18126-18188/? W/System.err: at com.binguokeji.sdk.library.Workflow$1.run(***.java:42)
12-17 14:08:38.590 18126-18188/? W/System.err: at java.lang.Thread.run(Thread.java:818)
12-17 14:08:38.590 18126-18188/? W/System.err: Caused by: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
12-17 14:08:38.590 18126-18188/? W/System.err: at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:324)
12-17 14:08:38.590 18126-18188/? W/System.err: at com.android.org.conscrypt.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:225)
12-17 14:08:38.590 18126-18188/? W/System.err: at com.android.org.conscrypt.Platform.checkServerTrusted(Platform.java:115)
12-17 14:08:38.590 18126-18188/? W/System.err: at com.android.org.conscrypt.OpenSSLSocketImpl.verifyCertificateChain(OpenSSLSocketImpl.java:643)
12-17 14:08:38.590 18126-18188/? W/System.err: at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
12-17 14:08:38.590 18126-18188/? W/System.err: at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:353)
12-17 14:08:38.590 18126-18188/? W/System.err: ... 14 more
12-17 14:08:38.590 18126-18188/? W/System.err: Caused by: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
12-17 14:08:38.590 18126-18188/? W/System.err: ... 20 more
有道上翻譯的錯誤資訊為----->沒有找到認證路徑的信任錨。 就是因為HTTPS請求有一層ssl加密協議,沒有認證的話是不能隨意訪問的
3.為HTTPS請求設定信任證書
public void setCertificates(HttpsURLConnection httpsURLConnection , InputStream... certificates) { try { CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); keyStore.load(null); int index = 0; for (InputStream certificate : certificates) { String certificateAlias = Integer.toString(index++); keyStore.setCertificateEntry(certificateAlias, certificateFactory.generateCertificate(certificate)); try { if (certificate != null) certificate.close(); } catch (IOException e) { } } SSLContext sslContext = SSLContext.getInstance("TLS"); TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); trustManagerFactory.init(keyStore); sslContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom()); httpsURLConnection.setSSLSocketFactory(sslContext.getSocketFactory()); } catch (Exception e) { e.printStackTrace(); } }在上邊post請求的時候做一下判斷
URL url = new URL(requestUrl); if (url.getProtocol().toUpperCase().equals("HTTPS")){ httpsURLConnection = (HttpsURLConnection) url.openConnection(); setCertificates(httpsURLConnection , new ByteArrayInputStream("信任證書的key".getBytes("UTF-8")); httpURLConnection = httpsURLConnection; } httpURLConnection = (HttpURLConnection) url.openConnection();這樣就可以實現HTTPS型別地址的訪問了