SSL pinning with Certificate : iOS
SSL pinning with Certificate

SSL pinning with Certificate : iOS

We use SSL pinning to ensure that the app communicates only with the designated server itself. One of the prerequisites for SSL pinning is saving the target’s server SSL certificate within the app bundle. The saved certificate is used when defining the pinned certificate(s) upon session configuration.

Simple steps (here we are using?newsAPI)

  1. First download server certificate and put in bundle (project) (sni.cloduflaressl.com in our case or leaf one)


No alt text provided for this image

2. Now just we have to convert both certs to Data and then compare and that's all if both are equal then we are good to go otherwise raise error.

Implementation using URLSession

class NetworkManger: NSObject {
    
    var session: URLSession?
    
    override init() {
        super.init()
        self.session = URLSession(configuration: URLSessionConfiguration.default, delegate: self, delegateQueue: nil)
    }
  
//  func getNewsAPI(... ) {}

}        

First you have to create URL session with delegate pattern only.

Then will implement logic didReceive challenge delegate method like this :


    func urlSession(_ session: URLSession
                    didReceive challenge: URLAuthenticationChallenge,
                    completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
        
        guard let serverTrust = challenge.protectionSpace.serverTrust,
              let serverCertificate = SecTrustGetCertificateAtIndex(serverTrust, 0) else {
            return
        }
        
        // 0 means we want only leaf certificate from list as you can see in above screensshost
        
        // Set SSL policies for domain name check
        let policies = NSMutableArray()
        policies.add(SecPolicyCreateSSL(true, (challenge.protectionSpace.host as CFString)))
        SecTrustSetPolicies(serverTrust, policies) 
        
        // certificate Pinning
                    
        let isServerTrust = SecTrustEvaluateWithError(serverTrust, nil)
        
        // local and server data
        // evalutate the certificate
        let remoteCertData: NSData = SecCertificateCopyData(serverCertificate)
        let localCertData: NSData = getLocalCertData()
        
        // compare both data
        if isServerTrust && remoteCertData.isEqual(to: localCertData as Data) {
            let credential = URLCredential(trust: serverTrust)
            print("certificate pinning is successful")
            completionHandler(.useCredential, credential
            )
        } else {
            completionHandler(.cancelAuthenticationChallenge, nil)
        }
    }        
No alt text provided for this image

For full code, please check this repo

https://github.com/pradeepkas/SSLPinningNative

References :

https://www.bugsee.com/blog/ssl-certificate-pinning-in-mobile-applications/

https://newsapi.org/

Thank You for reading this !! Happy coding



要查看或添加评论,请登录

Pradeep Kumar的更多文章

社区洞察

其他会员也浏览了