iOS8 系統上WKWebView https 證書不驗證問題

來這里,了解很多問題,發掘更多。
?????? 傳送門->Have-a-problem??????

??????:以下內容來自于傳送門鏈接??????

詳細過程:

WKWebView在iOS8上加載https(無效證書)出錯,通過各種資料查詢是WKWebView沒有走證書處理的方法(下面會給出),更何況證書不符合apple的要求。

Log輸出:

NSURLConnection/CFURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9814)

https關于服務器支持要求:

  • 服務器必須支持傳輸層安全(TLS)協議1.2以上版本
  • 證書必須使用SHA256或更高的哈希算法簽名
  • 必須使用2048位以上RSA密鑰或256位以上ECC算法等

?? 檢測你的地址是否支持ATS->??????傳送門??????

我目前的處理

  • iOS8及以下系統 使用UIWebView
  • iOS9及以上系統 使用WKWebView

需要注意

iOS8及以下系統,使用UIWebView的時候,任然需要忽略證書(其實這個取決于你們服務端愿不愿去支持ATS),如果不愿意或者說你跳的第三方根本就無法修改,那還是老老實實的忽略吧,不管那么多了,直接忽略??????

放大招(示例代碼)

控件及變量

// UIWebView 
var webViewIOS8: UIWebView?
var requestIOS8: URLRequest?
// WKWebView
var webViewIOS9: WKWebView?
// Other
var authed: Bool = false
var urlConnection: NSURLConnection?

根據系統版本選擇控件

if #available(iOS 9.0, *) {
    let request: URLRequest = URLRequest.init(url: URL.init(string: "鏈接地址")!)
    view.addSubview(webViewIOS9)
    webViewIOS9.load(request)
}else{
    requestIOS8 = URLRequest.init(url: URL.init(string: "鏈接地址")!)
    view.addSubview(webViewIOS8)
    webViewIOS8.loadRequest(requestIOS8!)
}

iOS8及以上忽略證書

func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {
    // 重新賦值requestIOS8
    requestIOS8 = request
    // 判斷是否https
    if (requestIOS8?.url?.absoluteString.hasPrefix("https"))! && !authenticated{
        authenticated = false
        // 使用NSURLConnection
        urlConnection = NSURLConnection.init(request: request, delegate: self)
        // 開始
        urlConnection?.start()
        return false
    }
    return true
}

func webViewDidFinishLoad(_ webView: UIWebView) {
    // 控制使用NSURLConnection
    authenticated = (requestIOS8?.url?.absoluteString.hasPrefix("https"))!
}

func webView(_ webView: UIWebView, didFailLoadWithError error: Error) {
    // 錯誤打印    
}

// MARK: NSURLConnectionDelegate
// 我對這部分的理解就是不去驗證證書的真偽,直接信任服務端
func connection(_ connection: NSURLConnection, didReceive challenge: URLAuthenticationChallenge) {
    // 創建憑據對象
    let cred = URLCredential(trust: challenge.protectionSpace.serverTrust!)
    // 告訴服務器信任證書
    challenge.sender?.use(cred, for: challenge)
}

func connection(_ connection: NSURLConnection, didReceive response: URLResponse) {
    // 控制使用NSURLConnection
    authenticated = true
    // 重新加載
    webViewIOS8.loadRequest(requestIOS8!)
    // 取消
    urlConnection?.cancel()
}

func connection(_ connection: NSURLConnection, canAuthenticateAgainstProtectionSpace protectionSpace: URLProtectionSpace) -> Bool {
    return true
}

iOS9及以上忽略證書

func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
    // 創建憑據對象
    let cred = URLCredential(trust: challenge.protectionSpace.serverTrust!)
    // 告訴服務器信任證書
    completionHandler(.useCredential, cred)
}

注意

以上內容為個人整理,如果有問題有出入或者你有更好的解決方法,還請賜教哦,感謝。
我的郵箱 coderjianfeng@foxmail.com ?????? github傳送門

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容