美文网首页
iOS Swift 适配HTTPS(单向验证)

iOS Swift 适配HTTPS(单向验证)

作者: just东东 | 来源:发表于2019-10-09 14:51 被阅读0次

前言

注意!!!

如果您使用的不是自签名的证书则不需要如下配置,比如顶级域名提供的证书、各种云服务提供的证书。

1.使用Alamofire

let manager = SessionManager.default
        manager.delegate.sessionDidReceiveChallenge = { session, challenge in
            
            if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
                MyLog("服务端证书认证!")
                
                let serverTrust:SecTrust = challenge.protectionSpace.serverTrust!
                let certificate = SecTrustGetCertificateAtIndex(serverTrust, 0)!
                let remoteCertificateData = CFBridgingRetain(SecCertificateCopyData(certificate))!
                let cerPath: String = Bundle.main.path(forResource: DDUrlTool.shared.getCAName(), ofType: nil) ?? ""
                let cerUrl = URL(fileURLWithPath:cerPath)
                let localCertificateData = try! Data(contentsOf: cerUrl)
                if remoteCertificateData.isEqual(localCertificateData) == true {
                    let credential = URLCredential(trust: serverTrust)
                    challenge.sender?.use(credential, for: challenge)
                    return (URLSession.AuthChallengeDisposition.useCredential,
                            URLCredential(trust: challenge.protectionSpace.serverTrust!))
                } else {
                    return (.cancelAuthenticationChallenge, nil)
                }
            } else {
                MyLog("其它情况(不接受认证)")
                return (.cancelAuthenticationChallenge, nil)
            }
        }

2.使用Alamofire + Moya

// 初始化provider
static let provider = MoyaProvider<ApiManager>(manager: getServiceManager(), plugins:[networkPlugin, networkLoggerPlugin])
private static func getServiceManager() -> Manager {
        let configuration = URLSessionConfiguration.default
        configuration.httpAdditionalHeaders = Manager.defaultHTTPHeaders
        
        let path: String = Bundle.main.path(forResource: "name", ofType: nil) ?? ""
        let certificationData = try? Data(contentsOf: URL(fileURLWithPath: path)) as CFData
        
        let certificate = SecCertificateCreateWithData(nil, certificationData!)
        let certificates: [SecCertificate] = [certificate!]
        
        let policies: [String: ServerTrustPolicy] = [kServiceDomain: ServerTrustPolicy.pinCertificates(certificates: certificates, validateCertificateChain: true, validateHost: true)]
        let manager = Manager(configuration: configuration, serverTrustPolicyManager: ServerTrustPolicyManager(policies: policies))
        return manager
    }

3.原生URLSession

/// 初始化 session
let session = URLSession.init(configuration: .default, delegate: self, delegateQueue: .main)
// delegate
public func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
        if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
            let serverTrust:SecTrust = challenge.protectionSpace.serverTrust!
            let certificate = SecTrustGetCertificateAtIndex(serverTrust, 0)!
            let remoteCertificateData = CFBridgingRetain(SecCertificateCopyData(certificate))!
            let cerPath: String = Bundle.main.path(forResource:"name", ofType: nil) ?? ""
            let cerUrl = URL(fileURLWithPath:cerPath)
            let localCertificateData = try! Data(contentsOf: cerUrl)
            if remoteCertificateData.isEqual(localCertificateData) == true {
                let credential = URLCredential(trust: serverTrust)
                challenge.sender?.use(credential, for: challenge)
                completionHandler(.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!))
            } else {
                completionHandler(.cancelAuthenticationChallenge, nil)
            }
        }
    }

4.WKWebView

    func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
        if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
            let serverTrust:SecTrust = challenge.protectionSpace.serverTrust!
            let certificate = SecTrustGetCertificateAtIndex(serverTrust, 0)!
            let remoteCertificateData = CFBridgingRetain(SecCertificateCopyData(certificate))!
            let cerPath: String = Bundle.main.path(forResource: "name", ofType: nil) ?? ""
            let cerUrl = URL(fileURLWithPath:cerPath)
            let localCertificateData = try! Data(contentsOf: cerUrl)
            if remoteCertificateData.isEqual(localCertificateData) == true {
                let credential = URLCredential(trust: serverTrust)
                challenge.sender?.use(credential, for: challenge)
                completionHandler(.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!))
            } else {
                completionHandler(.cancelAuthenticationChallenge, nil)
            }
        }
    }

5.Kingfisher

        let downloader = KingfisherManager.shared.downloader
        downloader.trustedHosts = Set([kServiceDomain])

相关文章

网友评论

      本文标题:iOS Swift 适配HTTPS(单向验证)

      本文链接:https://www.haomeiwen.com/subject/xakgpctx.html