SSL Pinning in iOS
SSL (Secure Sockets Layer) :-
SSL is a protocol for establishing secure communication links between networked computers. SSL/TLS is widely used to secure communication across the internet, particularly for sensitive transactions such as online banking, e-commerce and other sensitive information exchange.
SSL Pinning :-
SSL Pinning is a security technique used to prevent man-in-the-middle attacks by ensuring that an app only communicates with the intended server and not a malicious one.
Overview of how SSL Pinning works in iOS
When an iOS app makes a request to a server, the app first checks the server’s SSL/TLS certificate against a set of predefined “pinned” certificates. If the certificate presented by the server matches one of the pinned certificates, the connection is established. If the certificate does not match, the connection is terminated.
Here is a high-level overview of the process:
- The app makes a request to a server.
- The server presents its SSL/TLS certificate to the app.
- The app checks the certificate against a set of predefined “pinned” certificates.
- If the certificate matches, the connection is established and data can be exchanged securely.
- If the certificate does not match, the connection is terminated and the app may display an error message.
It is important to note that SSL Pinning should be implemented correctly and regularly updated, as an incorrect implementation can actually make the app less secure. Also, the app should handle correctly the revocation of the certificate.
implementation of SSL Pinning on iOS?
import Foundation
class SSLPinning: NSObject {
static let shared = SSLPinning()
// Create an array to store the public keys of the trusted certificates
let trustedCertificates: [SecCertificate] = [
SecCertificateCreateWithData(nil, Data(base64Encoded: "certificate1")! as CFData)!,
SecCertificateCreateWithData(nil, Data(base64Encoded: "certificate2")! as CFData)!
]
func pin(url: URL, completion: @escaping (Data?, URLResponse?, Error?) -> Void) {
let request = URLRequest(url: url)
let session = URLSession(configuration: .default, delegate: self, delegateQueue: nil)
let task = session.dataTask(with: request, completionHandler: completion)
task.resume()
}
}
extension SSLPinning: URLSessionDelegate {
func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
// Check if the certificate is trusted
if let serverTrust = challenge.protectionSpace.serverTrust,
SecTrustGetCertificateCount(serverTrust) > 0 {
let serverCertificate = SecTrustCopyCertificateChain(serverTrust)!
let serverCertificateData = SecCertificateCopyData(serverCertificate as! SecCertificate) as Data
for trustedCertificate in trustedCertificates {
let trustedCertificateData = SecCertificateCopyData(trustedCertificate) as Data
if serverCertificateData == trustedCertificateData {
completionHandler(.useCredential, URLCredential(trust: serverTrust))
return
}
}
}
// If the certificate is not trusted, cancel the request
completionHandler(.cancelAuthenticationChallenge, nil)
}
}
The code defines a class named SSLPinning, which contains an array of trusted certificates represented by SecCertificate objects. The class also has a function named “pin” which accepts a url and a completion handler.
The SSLPinning class also conforms to the URLSessionDelegate protocol, which requires it to implement the urlSession(_:didReceive:completionHandler:) method. This method is called when the server sends a challenge to the app, which is usually a request for authentication. The method checks if the certificate provided by the server is trusted by comparing it with the array of trusted certificates. If a match is found, the request is completed by passing .useCredential and URLCredential(trust: serverTrust) to the completion handler, otherwise, the request is canceled by passing .cancelAuthenticationChallenge and nil to the completion handler.
It is important to note that this code is just an example and it should be modified to suit your specific use case. You should use your own trusted certificates, and make sure to keep them up-to-date to avoid any security vulnerabilities.
If you like this post, please share or comment on the post. Any sort of interaction is highly appreciated. Thank you !!!