Search code examples
alamofirefingerprintpinning

SSL Pinning with fingerprint in Alamofire


Has anyone seen a way to do pinning with Alamofire with the fingerprint instead of the public key?

Sorry if this has been answered, I haven't seen it anywhere.

Thanks


Solution

  • This ended up being pretty straight forward. The code below might not be perfect, my real code is doing some addtional checks, but this is most of it.

    The .SHA1Fingerprint is an extension method on SecCertificate that copies it into NSData and then converts it to a SHA1. I use RNCryptor to do that, but you can do it however.

    The isValidFingerprint just compares the result to each of my known fingerprint(s).

    This all hangs off my static Alamofire.Manager.

    manager.delegate.sessionDidReceiveChallenge = { session, challenge in
            var disposition: NSURLSessionAuthChallengeDisposition = .PerformDefaultHandling
            var credential: NSURLCredential?
    
            if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
                let host = challenge.protectionSpace.host
    
                if let serverTrust = challenge.protectionSpace.serverTrust {
    
                    let serverTrustPolicy = ServerTrustPolicy.PerformDefaultEvaluation(validateHost: true)
    
                    if serverTrustPolicy.evaluateServerTrust(serverTrust, isValidForHost: host) {
                        disposition = .UseCredential
                        credential = NSURLCredential(forTrust: serverTrust)
                    } else {
                        disposition = .CancelAuthenticationChallenge
                        return (disposition, credential)
                    }
    
                    for index in 0..<SecTrustGetCertificateCount(serverTrust) {
                        if let certificate = SecTrustGetCertificateAtIndex(serverTrust, index) {
                            if let fingerPrint = certificate.SHA1Fingerprint {
                                if isValidFingerprint(fingerPrint)  {
                                    return (disposition, credential)
                                }
                            }
                        }
                    }
                }
            }
            disposition = .CancelAuthenticationChallenge
            return (disposition, credential)
        }