NetworkingMidOpen-ended

How do you handle SSL pinning in iOS?

Explanation & Code

Answer: SSL pinning validates that the server's certificate matches a known copy embedded in the app, preventing man-in-the-middle attacks even with valid certificates.

Code Example:

class PinnedSessionDelegate: NSObject, URLSessionDelegate {
    func urlSession(_ session: URLSession,
                    didReceive challenge: URLAuthenticationChallenge,
                    completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {

        guard challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust,
              let serverTrust = challenge.protectionSpace.serverTrust else {
            completionHandler(.cancelAuthenticationChallenge, nil)
            return
        }

        // Load pinned certificate from bundle
        guard let certPath = Bundle.main.path(forResource: "api_cert", ofType: "cer"),
              let pinnedData = NSData(contentsOfFile: certPath),
              let serverCert = SecTrustGetCertificateAtIndex(serverTrust, 0) else {
            completionHandler(.cancelAuthenticationChallenge, nil)
            return
        }

        let serverData = SecCertificateCopyData(serverCert) as NSData
        if serverData.isEqual(to: pinnedData as Data) {
            completionHandler(.useCredential, URLCredential(trust: serverTrust))
        } else {
            completionHandler(.cancelAuthenticationChallenge, nil)
        }
    }
}

let session = URLSession(configuration: .default,
                         delegate: PinnedSessionDelegate(),
                         delegateQueue: nil)

Rate your understanding:

Ready to practice more Networking?

Test yourself with our interactive quiz mode or browse all curated questions for this topic.