Last active
March 7, 2026 01:27
-
-
Save codewithsanthoshofficial/e580244664fc83e305d3d611b584df72 to your computer and use it in GitHub Desktop.
SSL Pinning
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 1) | |
| ###WithOut SSL Pinning | |
| extension NetworkManager: URLSessionDelegate { | |
| public func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { | |
| let urlCredential = URLCredential(trust: challenge.protectionSpace.serverTrust!) | |
| completionHandler(.useCredential, urlCredential) | |
| } | |
| } | |
| ### By Using Certificate.cer with No PEM | |
| Terminal - Get Keys likes: openssl x509 -inform DER -in yourcertificate.cer -noout -fingerprint -sha256 | |
| 2) | |
| ### Public Key Pinning | |
| extension NetworkManager : URLSessionDelegate { | |
| public 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 | |
| } | |
| var certificates: [SecCertificate] = [] | |
| if #available(iOS 15.0, *) { | |
| // iOS 15 and above | |
| if let certChain = SecTrustCopyCertificateChain(serverTrust) as? [SecCertificate] { | |
| certificates = certChain | |
| } | |
| } else { | |
| // Older iOS versions | |
| for index in 0..<SecTrustGetCertificateCount(serverTrust) { | |
| if let certificate = SecTrustGetCertificateAtIndex(serverTrust, index) { | |
| certificates.append(certificate) | |
| } | |
| } | |
| } | |
| for certificate in certificates { | |
| if let serverPublicKey = SecCertificateCopyKey(certificate), | |
| let serverPublicKeyData = SecKeyCopyExternalRepresentation(serverPublicKey, nil) as Data? { | |
| let keyHash = sha256(data: serverPublicKeyData) | |
| // Debug prints | |
| print("Server Public Key Data: \(serverPublicKeyData)") | |
| print("Key Hash: \(keyHash)") | |
| let key1 = "huhu/yrtyjkvhv67bvvfdd/bjbjbjbjjbjrdrddfdcc=" | |
| let key2 = "HYTHMK+OIJMNM/gygygygg6gvnbmmnkjjggffdffghjh=" | |
| if keyHash == key1 || keyHash == key2 { | |
| completionHandler(.useCredential, URLCredential(trust: serverTrust)) | |
| print("Authentication Successful") | |
| return | |
| }else{ | |
| print("Authentication Cancelled") | |
| } | |
| } | |
| } | |
| completionHandler(.cancelAuthenticationChallenge, nil) | |
| } | |
| private func sha256(data: Data) -> String { | |
| let rsa4096Asn1Header: [UInt8] = [ | |
| 0x30, 0x82, 0x02, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, | |
| 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x02, 0x0f, 0x00 | |
| ] | |
| var keyWithHeader = Data(rsa4096Asn1Header) | |
| keyWithHeader.append(data) | |
| var hash = [UInt8](repeating: .zero, count: Int(CC_SHA256_DIGEST_LENGTH)) | |
| keyWithHeader.withUnsafeBytes { | |
| _ = CC_SHA256($0.baseAddress, CC_LONG(keyWithHeader.count), &hash) | |
| } | |
| return Data(hash).base64EncodedString() | |
| } | |
| 3) | |
| ### Certificate Pinning | |
| func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Swift.Void) { | |
| // Adapted from OWASP https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning#iOS | |
| if (challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust) { | |
| let policy = NSMutableArray() | |
| policy.add(SecPolicyCreateSSL(true, challenge.protectionSpace.host as CFString)) | |
| if let serverTrust = challenge.protectionSpace.serverTrust { | |
| var secresult = SecTrustResultType.invalid | |
| let status = SecTrustEvaluateWithError(serverTrust, nil) | |
| if (status) { | |
| if let serverCertificate = SecTrustGetCertificateAtIndex(serverTrust, 0) { | |
| let serverCertificateData:NSData = SecCertificateCopyData(serverCertificate) | |
| let bundle = Bundle(for: Self.self) | |
| //need to have cer with no PEM | |
| let file_der = bundle.path(forResource: "new_Certificate__com", ofType: "cer") | |
| if let file = file_der { | |
| if let cert2 = NSData(contentsOfFile: file) { | |
| if serverCertificateData.isEqual(to: cert2 as Data) { | |
| completionHandler(URLSession.AuthChallengeDisposition.useCredential, URLCredential(trust:serverTrust)) | |
| return | |
| }else{ | |
| print("Authentication Cancelled") | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| // Pinning failed | |
| completionHandler(URLSession.AuthChallengeDisposition.cancelAuthenticationChallenge, nil) | |
| } | |
codewithsanthoshofficial
commented
Mar 7, 2026
Author


Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment