Friday, July 21, 2017

SSL pinning in iOS Swift code



SSL (Secure Socket Layer) pinning is used to prevent Man In The Middle attack.
This is generally used for secure end-to-end communication. Most the apps that requires secure communication such as Banking apps uses this mechanism.

You can implement this using Alamofire as below:

1. Ask Middleware team to implement SSL certificate on Server
2. They will give you .crt file
3. Now, convert this .crt file to .der online using https://www.sslshopper.com/ssl-converter.html
4. Add this .der file to your Xcode (Make sure that you checkmark copy items if needed on dialog box)
5. Now use below code for SSL Pinning in file where you make service calls:

var serverTrustPolicy:ServerTrustPolicy?
var serverTrustPolicies:[String: ServerTrustPolicy]?
var afManager: Alamofire.SessionManager?

if self.configureAlamoFireSSLPinning() == false {
            DispatchQueue.main.async() {
                let alert = UIAlertView(title: "", message: sslConfigurationError, delegate: nil, cancelButtonTitle: "OK")
                alert.show()                
            }
            return
        }


func configureAlamoFireSSLPinning() -> Bool {
        let githubCert = “APPNAME.COMPANYNAME.COM" // This name would be same as that of .der file
        let pathToCert = Bundle.main.path(forResource: githubCert, ofType: "der")
        let localCertificate:NSData = NSData(contentsOfFile: pathToCert!)!
        
        self.serverTrustPolicy = ServerTrustPolicy.pinCertificates(
            certificates: [SecCertificateCreateWithData(nil, localCertificate)!],
            validateCertificateChain: true,
            validateHost: true
        )
        
        self.serverTrustPolicies = [
            "github.com": self.serverTrustPolicy!
        ]
        
        let objConfiguration = URLSessionConfiguration.default
        objConfiguration.timeoutIntervalForResource = 600.0
        objConfiguration.timeoutIntervalForRequest = 30.0
        objConfiguration.urlCache = nil // Clear app cache
        
        self.afManager = Alamofire.SessionManager (
            configuration: objConfiguration,
            serverTrustPolicyManager: ServerTrustPolicyManager(policies: self.serverTrustPolicies!)
        )
        
        if self.afManager == nil {
            return false
        }
        
         return true
    }


6. Now make sure that you change the endpoint to https://