iOS certificate pinning with Swift and NSURLSession

前端 未结 7 824
无人及你
无人及你 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:43

    You can try this.

    import Foundation
    import Security
    
    class NSURLSessionPinningDelegate: NSObject, URLSessionDelegate {
    
          let certFileName = "name-of-cert-file"
          let certFileType = "cer"
    
          func urlSession(_ session: URLSession, 
                      didReceive challenge: URLAuthenticationChallenge, 
                      completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Swift.Void) {
    
        if (challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust) {
            if let serverTrust = challenge.protectionSpace.serverTrust {
                var secresult = SecTrustResultType.invalid
                let status = SecTrustEvaluate(serverTrust, &secresult)
    
                if(errSecSuccess == status) {
                    if let serverCertificate = SecTrustGetCertificateAtIndex(serverTrust, 0) {
                        let serverCertificateData = SecCertificateCopyData(serverCertificate)
                        let data = CFDataGetBytePtr(serverCertificateData);
                        let size = CFDataGetLength(serverCertificateData);
                        let certificateOne = NSData(bytes: data, length: size)
                        let filePath = Bundle.main.path(forResource: self.certFileName, 
                                                             ofType: self.certFileType)
    
                        if let file = filePath {
                            if let certificateTwo = NSData(contentsOfFile: file) {
                                if certificateOne.isEqual(to: certificateTwo as Data) {
                                    completionHandler(URLSession.AuthChallengeDisposition.useCredential, 
                                                      URLCredential(trust:serverTrust))
                                    return
                                }
                            }
                        }
                    }
                }
            }
        }
    
        // Pinning failed
        completionHandler(URLSession.AuthChallengeDisposition.cancelAuthenticationChallenge, nil)
    }
    }
    

    Source: https://www.steveclarkapps.com/using-certificate-pinning-xcode/

提交回复
热议问题