Android https請求證書處理

前言

在Android項目開發過程中,我們目前常用到的網絡框架基本都是基於Okhttp,Https協議在APP的開發中也被應用的越來越多,Okhttp默認是
支持https請求的,但是支持的Https網站必須是CA機構認證了的,對於自簽名的網址,還是不能訪問的,訪問直接拋出如下異常信息:
onFailure: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
對於https協議的處理,目前兩種方式
  • 客戶端默認信任全部證書
  • 對自簽名網址進行證書的單獨處理
客戶端默認信任全部證書

這個方式實現起來簡單,但是因爲信任了全部證書,會有一定的風險!使用者需注意,下面瞭解一下具體的實現

  1. 創建信任管理器的基本接口X509TrustManager
    //獲取TrustManager
    private static TrustManager[] getTrustManager() {
        //不校檢證書鏈
        TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    @Override
                    public void checkClientTrusted(X509Certificate[] chain, String authType) {
                        //不校檢客戶端證書
                    }

                    @Override
                    public void checkServerTrusted(X509Certificate[] chain, String authType) {
                        //不校檢服務器證書
                    }

                    @Override
                    public X509Certificate[] getAcceptedIssuers() {
                        return new X509Certificate[]{};
                        //OKhttp3.0以前返回null,3.0以後返回new X509Certificate[]{};
                    }
                }
        };
        return trustAllCerts;
    }

2. 創建SSLSocketFactory

    //獲取這個SSLSocketFactory
    //通過這個類我們可以獲得SSLSocketFactory,這個東西就是用來管理證書和信任證書的
    public static SSLSocketFactory getSSLSocketFactory() {
        try {
            SSLContext sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, getTrustManager(), new SecureRandom());
            return sslContext.getSocketFactory();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


//獲取HostnameVerifier
    public static HostnameVerifier getHostnameVerifier() {
        HostnameVerifier hostnameVerifier = new HostnameVerifier() {
            @Override
            public boolean verify(String s, SSLSession sslSession) {
                //未真正校檢服務器端證書域名
                return true;
            }
        };
        return hostnameVerifier;
    }

3. Okhttp相關配置

public OkHttpClient getOkHttpClient() {
        if (mOkHttpClient == null) {
            mOkHttpClient = new OkHttpClient.Builder()
                    .connectTimeout(15, TimeUnit.SECONDS)
                    .sslSocketFactory(new SSLSocketClient().getSSLSocketFactory())//配置
                    .hostnameVerifier(new SSLSocketClient().getHostnameVerifier())//配置
                    // .readTimeout(10, TimeUnit.SECONDS)
                    .build();
        }
        return mOkHttpClient;
    }

信任證書的相關配置就準備好了

擴展

  • webview不能加載https圖片

原因

如果您的應用是面向 API 級別 21 或更高級別:
  • 默認情況下,系統會阻止混合內容和第三方 Cookie。要允許混合內容和第三方 Cookie,請分別使用
    setMixedContentMode()和 setAcceptThirdPartyCookies() 方法。

  • 系統現在可以智能地選擇要繪製的 HTML 文檔部分。這個新的默認行爲有助於減少內存佔用和提升性能。如果您要一次渲染整個文檔,可通過調用 enableSlowWholeDocumentDraw()`停用此優化。

如果您的應用是面向低於 21 的 API 級別:
  • 系統允許混合內容和第三方 Cookie,並始終一次渲染整個文檔。

解決方法

 //Android Lollipop(5.0)開始 webview默認不允許混合模式,https當中不能加載http資源,如果要加載,需單獨設置開啓。
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
          webView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
        }

對你有幫助記得點贊❥(^_-)

## 我的圖片選擇器—點擊移步github

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章