FileDownloader,Okhttp,HttpUrlConnection信任所有證書
在開發過程中遇到一個問題,有的連結是https 經過ssl加密的,還有的是自簽名證書,如果不進行處理的話會被攔截,無法訪問或下載,解決方式就是信任所有證書。這裡記錄一下,也希望能幫到其他人。
1.FileDownloader
//檔案下載器初始化 FileDownloader.setupOnApplicationOnCreate(this) .connectionCreator(new OkHttp3Connection.Creator(OkHttp3Connection.createOkHttp())) .commit();
/** * @author allyn. */ public class OkHttp3Connection implements FileDownloadConnection { final OkHttpClient mClient; private final Request.Builder mRequestBuilder; private Request mRequest; private Response mResponse; OkHttp3Connection(Request.Builder builder, OkHttpClient client) { mRequestBuilder = builder; mClient = client; } public OkHttp3Connection(String url, OkHttpClient client) { this(new Request.Builder().url(url), client); } @Override public void addHeader(String name, String value) { mRequestBuilder.addHeader(name, value); } @Override public boolean dispatchAddResumeOffset(String etag, long offset) { return false; } @Override public InputStream getInputStream() throws IOException { if (mResponse == null) throw new IOException("Please invoke #execute first!"); final ResponseBody body = mResponse.body(); if (body == null) throw new IOException("No body found on response!"); return body.byteStream(); } @Override public Map<String, List<String>> getRequestHeaderFields() { if (mRequest == null) { mRequest = mRequestBuilder.build(); } return mRequest.headers().toMultimap(); } @Override public Map<String, List<String>> getResponseHeaderFields() { return mResponse == null ? null : mResponse.headers().toMultimap(); } @Override public String getResponseHeaderField(String name) { return mResponse == null ? null : mResponse.header(name); } @Override public boolean setRequestMethod(String method) throws ProtocolException { mRequestBuilder.method(method, null); return true; } @Override public void execute() throws IOException { if (mRequest == null) { mRequest = mRequestBuilder.build(); } mResponse = mClient.newCall(mRequest).execute(); } @Override public int getResponseCode() throws IOException { if (mResponse == null) throw new IllegalStateException("Please invoke #execute first!"); return mResponse.code(); } @Override public void ending() { mRequest = null; mResponse = null; } public static class Creator implements FileDownloadHelper.ConnectionCreator { private OkHttpClient mClient; private OkHttpClient.Builder mBuilder; public Creator() { } public Creator(OkHttpClient.Builder builder) { mBuilder = builder; } public OkHttpClient.Builder customize() { if (mBuilder == null) { mBuilder = new OkHttpClient.Builder(); } return mBuilder; } @Override public FileDownloadConnection create(String url) throws IOException { if (mClient == null) { synchronized (Creator.class) { if (mClient == null) { mClient = mBuilder != null ? mBuilder.build() : new OkHttpClient(); mBuilder = null; } } } return new OkHttp3Connection(url, mClient); } } /** * filedownload 使用okhttp作為下載引擎忽略掉SSL驗證, 新增證書不好使 * * @return */ public static OkHttpClient.Builder createOkHttp() { OkHttpClient.Builder builder = new OkHttpClient.Builder(); builder.connectTimeout(20_000, TimeUnit.SECONDS); builder.sslSocketFactory(createSSLSocketFactory(), new X509TrustManager() { @Override public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } }); builder.hostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { return true; } }); return builder; } @SuppressLint("TrulyRandom") public static SSLSocketFactory createSSLSocketFactory() { SSLSocketFactory sSLSocketFactory = null; try { SSLContext sc = SSLContext.getInstance("TLS"); sc.init(null, new TrustManager[]{new TrustAllManager()}, new SecureRandom()); sSLSocketFactory = sc.getSocketFactory(); } catch (Exception e) { } return sSLSocketFactory; } private static class TrustAllManager implements X509TrustManager { @Override public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public X509Certificate[] getAcceptedIssuers() { return null; } } }
2.Okhttp
OkHttpClient.Builder mBuilder=mBuilder = new OkHttpClient.Builder(); mBuilder.sslSocketFactory(createSSLSocketFactory()); mBuilder.hostnameVerifier(new TrustAllHostnameVerifier()); mBuilder.build();
/** * 預設信任所有的證書 * TODO 最好加上證書認證,主流App都有自己的證書 * * @return */ @SuppressLint("TrulyRandom") private static SSLSocketFactory createSSLSocketFactory() { SSLSocketFactory sSLSocketFactory = null; try { SSLContext sc = SSLContext.getInstance("TLS"); sc.init(null, new TrustManager[]{new TrustAllManager()}, new SecureRandom()); sSLSocketFactory = sc.getSocketFactory(); } catch (Exception e) { } return sSLSocketFactory; } private static class TrustAllManager implements X509TrustManager { @Override public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public X509Certificate[] getAcceptedIssuers() { return null; } } private static class TrustAllHostnameVerifier implements HostnameVerifier { @Override public boolean verify(String hostname, SSLSession session) { return new X509Certificate[0]; } }
3.HttpUrlConnection
URL url = new URL(url); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); if (url.startsWith("https")) { HttpsURLConnection https = (HttpsURLConnection) conn; https.setHostnameVerifier(DO_NOT_VERIFY); https.setSSLSocketFactory(trustAllHosts(https)); }
/** ** 覆蓋java預設的證書驗證 * */ static final TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() { public java.security.cert.X509Certificate[] getAcceptedIssuers() { return new java.security.cert.X509Certificate[]{}; } public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } }}; /** ** 設定不驗證主機 * */ public static final HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() { public boolean verify(String hostname, SSLSession session) { return true; } }; /** ** 信任所有 ** @param connection ** @return * */ public static SSLSocketFactory trustAllHosts(HttpsURLConnection connection) { SSLSocketFactory oldFactory = connection.getSSLSocketFactory(); try { SSLContext sc = SSLContext.getInstance("TLS"); sc.init(null, trustAllCerts, new java.security.SecureRandom()); SSLSocketFactory newFactory = sc.getSocketFactory(); connection.setSSLSocketFactory(newFactory); } catch (Exception e) { e.printStackTrace(); } return oldFactory; }