国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android webview手動校驗https證書(by 星空武哥)

2019-10-22 18:28:40
字體:
來源:轉載
供稿:網友

有些時候由于Android系統的bug或者其他的原因,導致我們的webview不能驗證通過我們的https證書,最明顯的例子就是華為手機mate7升級到Android7.0后,手機有些網站打不開了,而更新了webview的補丁后就沒問題了,充分說明系統的bug對我們混合開發webview加載https地址的影響是巨大的。那么我們怎么去解決這個問題呢?

webview,手動校驗,https證書,Android

首先我們去分析一下出現的原因
當webview加載https地址的時候,如果因為證書的問題出錯的時候就會走onReceivedSslError()方法

webView.setWebViewClient(new WebViewClient() {    @Override   public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {     super.onReceivedSslError(view, handler, error);   } } 

而super.onReceivedSslError()默認是

webview,手動校驗,https證書,Android

handler.cancel() 就是讓加載的頁面白屏,所有導致了如果webview校驗證書存在異常,android在默認情況下會顯示白屏,我們也可調用handler.proceed(),大多時候很多人都是這個處理,但是這也就意味著https證書失去了他存在的意義了。

webview,手動校驗,https證書,Android

那么如果你的網站證書是正常的,但是因為系統的bug導致了加載異常,這時候就需要我們手動校驗了。
其實我們是可以手動校驗網站證書的sha256,如果異常之后校驗sha256就執行handler.proceed(),失敗就退出應用。
首先我們要獲取網站的證書
利用谷歌瀏覽器,打開網址并且按下“F12”,打開開發者模式

webview,手動校驗,https證書,Android

一步一步導出證書

webview,手動校驗,https證書,Android

然后在打開sha256校驗網址:http://www.atool.org/file_hash.php

或http://tools.vevb.com/password/sha_encode

webview,手動校驗,https證書,Android

這樣就獲取到了證書的sha256的值,寫了一個工具類

  /**   * SSL證書錯誤,手動校驗https證書   *   * @param cert   https證書   * @param sha256Str sha256值   * @return true通過,false失敗   */  public static boolean isSSLCertOk(SslCertificate cert, String sha256Str) {    byte[] SSLSHA256 = hexToBytes(sha256Str);    Bundle bundle = SslCertificate.saveState(cert);    if (bundle != null) {      byte[] bytes = bundle.getByteArray("x509-certificate");      if (bytes != null) {        try {          CertificateFactory cf = CertificateFactory.getInstance("X.509");          Certificate ca = cf.generateCertificate(new ByteArrayInputStream(bytes));          MessageDigest sha256 = MessageDigest.getInstance("SHA-256");          byte[] key = sha256.digest(((X509Certificate) ca).getEncoded());          return Arrays.equals(key, SSLSHA256);        } catch (Exception e) {          e.printStackTrace();        }      }    }    return false;  }  /**   * hexString轉byteArr   * <p>例如:</p>   * hexString2Bytes("00A8") returns { 0, (byte) 0xA8 }   *   * @param hexString   * @return 字節數組   */  public static byte[] hexToBytes(String hexString) {    if (hexString == null || hexString.trim().length() == 0)      return null;    int length = hexString.length() / 2;    char[] hexChars = hexString.toCharArray();    byte[] bytes = new byte[length];    String hexDigits = "0123456789abcdef";    for (int i = 0; i < length; i++) {      int pos = i * 2; // 兩個字符對應一個byte      int h = hexDigits.indexOf(hexChars[pos]) << 4; // 注1      int l = hexDigits.indexOf(hexChars[pos + 1]); // 注2      if (h == -1 || l == -1) { // 非16進制字符        return null;      }      bytes[i] = (byte) (h | l);    }    return bytes;  }

然后在onReceivedSslError()判斷

webView.setWebViewClient(new WebViewClient() {	@Override	public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {		super.onReceivedSslError(view, handler, error);		if (error.getPrimaryError() == SslError.SSL_INVALID) {			// 如果手動校驗sha256成功就允許加載頁面			if (SSLCertUtil.isSSLCertOk(error.getCertificate(), "6683c9584b8287ec3a50e312f4a540c79938aaeb76bd02e40a9ca037ee5d24f4")) {				handler.proceed();			} else {				try {					new AlertDialog.Builder(MainActivity.this)							.setTitle("警告")							.setMessage("證書校驗失敗")							.setPositiveButton("退出", new DialogInterface.OnClickListener() {								@Override								public void onClick(DialogInterface dialog, int which) {									System.exit(0);									dialog.dismiss();								}							}).show();				} catch (Exception e) {					e.printStackTrace();				}			}		} else {			handler.cancel();		}	}});

這里我們只是真對SslError.SSL_INVALID進行了判斷,可能還有其他情況,根據自己的情況判定。

/** * The certificate is not yet valid */public static final int SSL_NOTYETVALID = 0;/** * The certificate has expired */public static final int SSL_EXPIRED = 1;/** * Hostname mismatch */public static final int SSL_IDMISMATCH = 2;/** * The certificate authority is not trusted */public static final int SSL_UNTRUSTED = 3;/** * The date of the certificate is invalid */public static final int SSL_DATE_INVALID = 4;/** * A generic error occurred */public static final int SSL_INVALID = 5;

這樣就完成了手動校驗https證書校

 

注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 依安县| 扎赉特旗| 育儿| 靖安县| 景洪市| 原阳县| 大港区| 紫阳县| 通辽市| 苍南县| 东城区| 西峡县| 东港市| 西安市| 禹城市| 宁国市| 广元市| 土默特右旗| 新河县| 苍梧县| 景宁| 临漳县| 娄烦县| 甘肃省| 平安县| 叶城县| 天祝| 深水埗区| 垣曲县| 靖远县| 共和县| 云安县| 宜都市| 梅州市| 怀宁县| 平凉市| 蒙自县| 思茅市| 盘山县| 棋牌| 涪陵区|