日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android WebView https白屏、Http和Https混合问题、证书配置和使用

發布時間:2025/3/12 Android 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android WebView https白屏、Http和Https混合问题、证书配置和使用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

  • 前言
  • 啟用https后白屏(證書錯誤)
  • 修改處理
  • WebView中Http和Https混合問題
    • 處理辦法
    • Webview的幾種內容加載模式
  • 證書配置或處理
  • https請求的證書
    • okhttp進行請求:
    • HttpsURLConnection
    • 忽略證書

前言

原有項目中有部分界面是用webview展現的h5頁面,一直以來都使用的http地址,但有些情況下,用戶dns被劫持,頁面上出現了一些廣告的內容,或者頁面就是白屏,總結起來還是因為使用http,頁面內容被劫持修改,修改后的內容要么多出廣告,要么被修改得加載不出來,因此項目中自然就需要加載https的地址。同時修改為https之后,出現問題的那些用戶也能正常的顯示出h5頁面內容。

啟用https后白屏(證書錯誤)

然而,在新版本上線后,有客戶反饋oppo(8.1)、vivo等用戶反饋app中頁面白屏,單位的oppo和vivo驗證都沒有問題。最后小伙伴用模擬器復現了,同時也看到錯誤日志:

此處的日志是在WebChromeClient的重實現打出來的(代碼已經修改過):

@Overridepublic void onReceivedSslError(WebView webView, SslErrorHandler sslErrorHandler, SslError sslError) {GenseeLog.e(TAG,"onReceivedSslError sslErrorHandler = [" + sslErrorHandler + "], sslError = [" + sslError + "]");_onReceivedError();super.onReceivedSslError(webView, sslErrorHandler, sslError);}

修改處理

得知是在WebChromeClient的onReceivedSslError重實現中響應了相關的錯誤,在onReceivedSslError中調用sslErrorHandler.process(); 就可以了:忽略證書問題。

public void onReceivedSslError(WebView webView, SslErrorHandler sslErrorHandler, SslError sslError) {GenseeLog.e(TAG,"onReceivedSslError sslErrorHandler = [" + sslErrorHandler + "], sslError = [" + sslError.getPrimaryError() + "]");_onReceivedError();sslErrorHandler.proceed(); // super.onReceivedSslError(webView, sslErrorHandler, sslError);}

此處注意:不要調用super.onReceivedSslError(webView, sslErrorHandler, sslError),super的實現是sslErrorHandler.cancel();,終止訪問。

public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {handler.cancel();}

注意:文本是通過忽略證書的問題處理的,但從實質性的安全來說并沒起到作用。確認我們的證書是無誤的。唯獨幾個oppo(系統8.1)和vivo用戶有問題,目前沒有得到真機的驗證,推測還是系統證書下載問題。有知道的老鐵請留言,感謝之。
正確建議做法是做證書校驗:

webView.setWebViewClient(new WebViewClient() {overridepublic void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {String msg;switch(error.getPrimaryError()) {case: SslError.SSL_DATE_INVALIDmsg = "證書日期無效"break;case: SslError.SSL_EXPIREDmsg = "證書已過期。"break;case: SslError.SSL_IDMISMATCH msg = "主機名不匹配。"break;case: SslError.SSL_INVALID msg = "發生一般錯誤"break;case: SslError.SSL_MAX_ERRORmsg = "不同SSL錯誤的數量。"break;case: SslError.SSL_NOTYETVALIDmsg = "證書尚未生效。"break;case: SslError.SSL_UNTRUSTEDmsg = "證書頒發機構不受信任。" // 自定義證書會執行到這個分支來break;default:msg ="SSL證書錯誤,錯誤碼:"+ error.getPrimaryError();}Log.i("SSL錯誤:" + msg)if (error.getPrimaryError() == SslError.SSL_UNTRUSTED) {// 證書頒發機構不受信任,則我們需要判斷一下是否是我們自己的自定義證書,是的話就忽略這個錯誤CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");X509Certificate certificate = certificateFactory.generateCertificate(resources.openRawResource(R.raw.xxx)) ;Field mX509CertificateFiled = SslCertificate.getClass().getDeclaredField("mX509Certificate");mX509CertificateFiled .setAccessible( true);X509Certificate mX509Certificate = mX509CertificateFiled.get(error.certificate());val certificates = HandshakeCertificates.Builder().addTrustedCertificate(certificate) // 信任指定的自定義證書.addPlatformTrustedCertificates() // 信任系統的預裝證書,如果不信任系統證書的話,比如在訪問https://m.baidu.com時將會出錯.build()try {certificates.trustManager.checkServerTrusted(new X509Certificate []{mX509Certificate}), "RSA")Log.i("是我們的自定義證書")handler.proceed()} catch (e: java.lang.Exception) {Log.e(e, "非法證書")handle.cancel()}}} else {super.onReceivedSslError(view, handler, error)}} });

WebView中Http和Https混合問題

在一個頁面通過http請求的,但頁面內有https的資源,后者頁面是通過https訪問的,但頁面內有http的資源,這樣的混合,一般后者都存在問題,當前前者也可能存在問題。

處理辦法

在webview加載頁面之前,設置加載模式為MIXED_CONTENT_ALWAYS_ALLOW

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {webView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);}

在Android5.0之前,系統默認是采用的MIXED_CONTENT_ALWAYS_ALLOW模式,即總是允許WebView同時加載Https和Http;而從Android5.0開始,默認用MIXED_CONTENT_NEVER_ALLOW模式,即總是不允許WebView同時加載Https和Http。

如果都是自家的網頁,那這個問題還是從源頭上進行處理,頁面不要使用混合的方式。

官網給出的建議是,為了安全考慮,使用 MIXED_CONTENT_NEVER_ALLOW模式,但是在實際引用中,當我們的服務器已經升級到Https,但是一些頁面的資源是第三方的,我們不一定能要求第三方也都升級到Https,所以我們只能根據系統版本,用代碼去設置加載模式為MIXED_CONTENT_ALWAYS_ALLOW。

Webview的幾種內容加載模式

從Android5.0開始,當一個安全的站點(https)去加載一個非安全的站點(http)時,需要配置Webview加載內容的混合模式,一共有如下三種模式:

  • MIXED_CONTENT_NEVER_ALLOW:Webview不允許一個安全的站點(https)去加載非安全的站點內容(http),比如,https網頁內容的圖片是http鏈接。強烈建議App使用這種模式,因為這樣更安全。
  • MIXED_CONTENT_ALWAYS_ALLOW:在這種模式下,WebView是可以在一個安全的站點(Https)里加載非安全的站點內容(Http),這是WebView最不安全的操作模式,盡可能地不要使用這種模式。
  • MIXED_CONTENT_COMPATIBILITY_MODE:在這種模式下,當涉及到混合式內容時,WebView會嘗試去兼容最新Web瀏覽器的風格。一些不安全的內容(Http)能被加載到一個安全的站點上(Https),而其他類型的內容將會被阻塞。這些內容的類型是被允許加載還是被阻塞可能會隨著版本的不同而改變,并沒有明確的定義。這種模式主要用于在App里面不能控制內容的渲染,但是又希望在一個安全的環境下運行。

證書配置或處理

如果需要配置證書的情況下,
在res目錄下創建一個xml文件目錄,再創建一個network_security_config.xml(名字可隨意),然后就是在這個文件中寫入一些關于https的配置,接著把network_security_config配置到Anroidmanifest的Application節點屬性中,如下:

<applicationandroid:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:networkSecurityConfig="@xml/network_security_config"></application>

我們的xxx.crt的證書文件按照規范,需要放到res/raw/目錄下面。接著配置到network_security_config文件中。配置證書,有兩種方式,如下:

  • base-config
    表示應用的訪問的所有域名的資源都信任我們指定的xxx證書
  • <?xml version="1.0" encoding="utf-8"?> <network-security-config><base-config><trust-anchors><certificates src="@raw/xxx" /></trust-anchors></base-config> </network-security-config>
  • domain-config
    使用domain-config限制了gensee.com或它的子域名都信任我們指定的xxx證書
  • <?xml version="1.0" encoding="utf-8"?> <network-security-config><domain-config><domain includeSubdomains="true">gensee.com</domain><trust-anchors><certificates src="@raw/xxx"/></trust-anchors></domain-config> </network-security-config>
  • 指定信任預安裝的證書
    配置我們要信任什么證書,直接使用@raw/xxx為配置信任自定義的證書,如果要指定信任預安裝的證書,需要另外指定,預安裝的證書有系統和用戶兩種類型,如下:
  • <?xml version="1.0" encoding="utf-8"?> <network-security-config><base-config><trust-anchors><certificates src="@raw/custom_ca" /> <!--信任自定義的CA證書--><certificates src="system" /> <!--信任系統預裝的CA證書--><certificates src="user" /> <!--信任用戶安裝的CA證書--></trust-anchors></base-config> </network-security-config>

    https請求的證書

    okhttp進行請求:

    val builder = OkHttpClient.Builder() if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {val certificateFactory: CertificateFactory = CertificateFactory.getInstance("X.509")val certificate = certificateFactory.generateCertificate(resources.openRawResource(R.raw.xxx)) as X509Certificateval certificates = HandshakeCertificates.Builder().addTrustedCertificate(certificate) // 信任指定的自定義證書.addPlatformTrustedCertificates() // 信任系統的預裝證書,如果不信任系統證書的話,比如在訪問https://m.baidu.com時將會出錯.build()builder.sslSocketFactory(certificates.sslSocketFactory(), certificates.trustManager) } val okHttpClient = builder.build()

    HttpsURLConnection

    // Load CAs from an InputStream// (could be from a resource or ByteArrayInputStream or ...)val cf: CertificateFactory = CertificateFactory.getInstance("X.509")// From https://www.washington.edu/itconnect/security/ca/load-der.crtval caInput: InputStream = BufferedInputStream(FileInputStream("load-der.crt"))val ca: X509Certificate = caInput.use {cf.generateCertificate(it) as X509Certificate}System.out.println("ca=" + ca.subjectDN)// Create a KeyStore containing our trusted CAsval keyStoreType = KeyStore.getDefaultType()val keyStore = KeyStore.getInstance(keyStoreType).apply {load(null, null)setCertificateEntry("ca", ca)}// Create a TrustManager that trusts the CAs inputStream our KeyStoreval tmfAlgorithm: String = TrustManagerFactory.getDefaultAlgorithm()val tmf: TrustManagerFactory = TrustManagerFactory.getInstance(tmfAlgorithm).apply {init(keyStore)}// Create an SSLContext that uses our TrustManagerval context: SSLContext = SSLContext.getInstance("TLS").apply {init(null, tmf.trustManagers, null)}// Tell the URLConnection to use a SocketFactory from our SSLContextval url = URL("https://certs.cac.washington.edu/CAtest/")val urlConnection = url.openConnection() as HttpsURLConnectionurlConnection.sslSocketFactory = context.socketFactoryval inputStream: InputStream = urlConnection.inputStreamcopyInputStreamToOutputStream(inputStream, System.out)

    忽略證書

    /** 獲取一個SSLSocketFactory */ val sSLSocketFactory: SSLSocketFactoryget() = try {val sslContext = SSLContext.getInstance("SSL")sslContext.init(null, arrayOf(trustManager), SecureRandom())sslContext.socketFactory} catch (e: Exception) {throw RuntimeException(e)}/** 獲取一個忽略證書的X509TrustManager */ val trustManager: X509TrustManagerget() = object : X509TrustManager {override fun checkClientTrusted(chain: Array<X509Certificate>, authType: String) { } override fun checkServerTrusted(chain: Array<X509Certificate>, authType: String) { } override fun getAcceptedIssuers(): Array<X509Certificate> { return arrayOf() }}

    將這兩個對象設置給okhttp或HttpsURLConnection即可完成證書忽略。

    https://blog.csdn.net/android_cai_niao/article/details/108065766
    https://blog.csdn.net/luofen521/article/details/51783914

    總結

    以上是生活随笔為你收集整理的Android WebView https白屏、Http和Https混合问题、证书配置和使用的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 亚洲伦理一区二区 | 免费看女人裸体 | 久久噜| av老司机在线播放 | 亚洲欧美精品久久 | 色就色综合 | 精品一区二区三区毛片 | 男人天堂成人网 | 插插看 | 欧美一级一区二区三区 | 中文字幕人妻色偷偷久久 | 午夜老司机免费视频 | 欧美午夜性生活 | 国产精品第 | 色乱码一区二区三区在线男奴 | 都市激情久久 | 亚洲天码中字 | 怨女1988国语版在线观看高清 | 1024手机在线看片 | 在线观看www视频 | 性xxx欧美 | 亚洲成人精品视频 | 成人久久电影 | 天堂网视频在线观看 | 丝袜人妖 | 成人手机在线观看 | 男人免费网站 | 成人aaa视频 | 美女自拍视频 | 日韩黄色在线播放 | 在线能看的av网站 | 欧美日韩一区二区精品 | 成人在线视频观看 | 日韩一级完整毛片 | 日韩国产中文字幕 | 成人午夜毛片 | 波多野结衣乳巨码无在线观看 | 老子午夜影院 | 欧美aⅴ| 中日韩在线播放 | 人妻久久一区二区 | 中国a毛片| 国产成人免费片在线观看 | 草莓视频一区二区三区 | 在线视频免费观看 | 久久久久久片 | 妹子色综合| 亚洲熟妇无码av在线播放 | xxxxx亚洲 | 五月婷婷综合色 | 老色批影院 | www.jizzjizz.com| 91综合色 | 亚洲综合中文字幕在线 | 伊人精品影院 | 天天添天天操 | 久久久久成人精品无码中文字幕 | 国产三级漂亮女教师 | 性色网站 | 国产精品一区二区黑人巨大 | 大香依人 | 能看av的网站 | 日本三级全黄 | 中国丰满老太hd | 禁漫天堂免费网站 | 亚洲色图网址 | 无码精品久久久久久久 | 少妇按摩一区二区三区 | 国产77777| 国产欧美精品一区二区三区app | 喷水在线观看 | 中文av字幕| 亚洲区一区 | 日韩精品在线第一页 | 天天做夜夜做 | 欧美一区二三区 | 女av在线 | 天天插综合 | 夜夜操天天射 | 国产手机精品视频 | 久久精品99久久久久久久久 | 成人在线视频网站 | 少妇免费视频 | 亚洲精品鲁一鲁一区二区三区 | 精品熟妇一区二区三区 | 国产亚洲欧美在线视频 | 久久精品黄色 | 欧美视频不卡 | 秋葵视频污 | 波多野结衣视频在线观看 | 国产一级视频免费观看 | 欧美成人精品一区二区三区在线看 | 天天操妹子 | 911色 | 欧美成人极品 | 日韩欧美一级大片 | 国产激情四射 | 777奇米色 | 欧美色插 |