iOS certificate pinning with Swift and NSURLSession

前端 未结 7 839
无人及你
无人及你 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条回答
  •  慢半拍i
    慢半拍i (楼主)
    2020-12-07 18:43

    Here's an updated version for Swift 3

    import Foundation
    import Security
    
    class NSURLSessionPinningDelegate: NSObject, URLSessionDelegate {
    
        func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Swift.Void) {
    
            // Adapted from OWASP https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning#iOS
    
            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 cert1 = NSData(bytes: data, length: size)
                            let file_der = Bundle.main.path(forResource: "name-of-cert-file", ofType: "cer")
    
                            if let file = file_der {
                                if let cert2 = NSData(contentsOfFile: file) {
                                    if cert1.isEqual(to: cert2 as Data) {
                                        completionHandler(URLSession.AuthChallengeDisposition.useCredential, URLCredential(trust:serverTrust))
                                        return
                                    }
                                }
                            }
                        }
                    }
                }
            }
    
            // Pinning failed
            completionHandler(URLSession.AuthChallengeDisposition.cancelAuthenticationChallenge, nil)
        }
    
    }
    

提交回复
热议问题