iOS certificate pinning with Swift and NSURLSession

前端 未结 7 834
无人及你
无人及你 2020-12-07 18:04

Howto add certificate pinning to a NSURLSession in Swift?

The OWASP website contains only an example for Objective-C and NSURLConnection.

7条回答
  •  暖寄归人
    2020-12-07 18:33

    Save the certificate (as .cer file) of your website in the main bundle. Then use this URLSessionDelegate method:

    func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
    
        guard
            challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust,
            let serverTrust = challenge.protectionSpace.serverTrust,
            SecTrustEvaluate(serverTrust, nil) == errSecSuccess,
            let serverCert = SecTrustGetCertificateAtIndex(serverTrust, 0) else {
    
                reject(with: completionHandler)
                return
        }
    
        let serverCertData = SecCertificateCopyData(serverCert) as Data
    
        guard
            let localCertPath = Bundle.main.path(forResource: "shop.rewe.de", ofType: "cer"),
            let localCertData = NSData(contentsOfFile: localCertPath) as Data?,
    
            localCertData == serverCertData else {
    
                reject(with: completionHandler)
                return
        }
    
        accept(with: serverTrust, completionHandler)
    
    }
    

    ...

    func reject(with completionHandler: ((URLSession.AuthChallengeDisposition, URLCredential?) -> Void)) {
        completionHandler(.cancelAuthenticationChallenge, nil)
    }
    
    func accept(with serverTrust: SecTrust, _ completionHandler: ((URLSession.AuthChallengeDisposition, URLCredential?) -> Void)) {
        completionHandler(.useCredential, URLCredential(trust: serverTrust))
    }
    

提交回复
热议问题