Android APP之WebView如何校驗SSL證書

  Android系統的碎片化很嚴重,而且手機日期不正確、手機根證書異常、com.google.android.webview BUG等各類緣由,都會致使WebViewClient沒法訪問HTTPS站點。SSL錯誤的處理方式十分關鍵,若是處理不當,可能致使中間人攻擊,黑客竊聽數據,進而引起安全事故。html

  嚴謹地處理onReceivedSslError尤其重要。請參考如下代碼,原理是:若是webview報告SSL錯誤,程序將會對服務器證書進行強校驗,若是服務器傳入證書的指紋(sha256)與記錄值一致,說明webview驗證過程存在缺陷(如:手機日期錯誤、根證書被刪除 等),忽略SSL錯誤;若是證書匹配失敗,代表數據通訊有問題,保留阻斷。android

  請先點擊 這裏,獲取證書的指紋(sha256),而後調整代碼中的MySSLCNSHA256數組變量。若是APP須要訪問多張證書,請在代碼中加入多個證書指紋數值。在測試代碼時,請將手機日期設置在證書有效期以前,判斷WebView是否能正常訪問HTTPS站點。web

 

webview.setWebViewClient(new WebViewClient() {
    @Override
    public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
	if (error.getPrimaryError() == SslError.SSL_DATE_INVALID  // 日期不正確
    		|| error.getPrimaryError() == SslError.SSL_EXPIRED // 日期不正確
    		|| error.getPrimaryError() == SslError.SSL_INVALID // webview BUG
    		|| error.getPrimaryError() == SslError.SSL_UNTRUSTED) { // 根證書丟失
    		if (chkMySSLCNCert(error.getCertificate())) {
		        handler.proceed();  // 若是證書一致,忽略錯誤
    		}
	}
    }
    
    private boolean chkMySSLCNCert(SslCertificate cert) {
	byte[] MySSLCNSHA256 = { 35, 76, 110, -121, -68, -104, -12, 84, 39, 119, -55,
    		101, 95, -8, -90, 9, 36, -108, 5, -57, 76, -98, -19, -73, 91, -37, 18,
    		64, 32, -41, 0, 109 };  //證書指紋
    	Bundle bundle = SslCertificate.saveState(cert);
    	byte[] bytes = bundle.getByteArray("x509-certificate");
    	if (bytes != null) {
    		try {
	            CertificateFactory cf = CertificateFactory.getInstance("X.509");  
	            Certificate ca = cf.generateCertificate(new ByteArrayInputSteam(bytes));  
	            MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
	            byte[] Key = sha256.digest(((X509Certificate) ca).getEncoded());
	            return Arrays.equals(key, MySSLCNSHA256);
    		} catch (Exception Ex) {}
    	}
    	return false;
    }
}

 

  原創文章,轉載請註明文章來源 https://www.myssl.cn數組

相關文章
相關標籤/搜索