In today’s advance environment, everybody will be comfortable with automation rather than applying manual efforts.
With Trustkit, one can easily validate the certificate’s public key by typing only a few lines of codes and also, it comes with extra functionalities like reporting or fallback public keys.
Step 1: Extracting the public key of the certificate
Firstly, one has to download the actual certificate used by the server. Here, I am using the google certificate for the testing purpose. Extract certificate with the below command:
openssl s_client -showcerts -connect www.google.co.uk:443 < /dev/null | openssl x509 -outform DER > google.cer
Note: Change the format of the downloaded certificate from .cer to .pem (which is the accepted format of TrustKit). Here, I renamed the google certificate ‘google.cer’ to ‘googleSSL.cer’ for better understanding. Use below command to change the file format:
openssl x509 -inform der -in googleSSL.cer -out certificate.pem
And finally, use the below command to extracts the public key for the pinning:
cat certificate.pem | openssl rsa -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64
Step 2: Installation
Now that one has extracted the public key, set up the TrustKit by installing TrustKit by using pods and add TrustKit in the project.
Add below line in your pod file and install the pod.
pod 'TrustKit'
Step 3: TrustKit configuration
There are two ways to configure TrustKit. The first way is by Adding keys and values to info.plist file which could be achieved by below code:
<key>TSKConfiguration</key> <dict> <key>TSKPinnedDomains</key> <dict> <key>myDomain.com</key> <dict> <key>TSKPublicKeyHashes</key> <array> <string>public key 1</string> <string>public key 2</string> </array> <key>TSKPublicKeyAlgorithms</key> <array> <string>TSKAlgorithmRsa2048</string> </array> <key>TSKIncludeSubdomains</key> <true/> <key>TSKEnforcePinning</key> <true/> </dict> </dict> </dict>
The second public key i.e. public key 2 (in the code above) is the backup key. So, if, there is some issue with the first key, the application will work properly with the second key (backup key).
One has to add two mandatory keys: kTSKPublicKeyAlgorithms and kTSKPublicKeyHashes to make the configuration works properly. Here, the key kTSKPublicKeyAlgorithms specifies the encoding method of the public key and the kTSKPublicKeyHashes define the hashed version of the public key.
Note: One has to provide at least two public keys for the pinning. The first key is from the main certificate and another key is from the backup certificate key.
The second way is by Adding the same keys and values by code in your Appdelegate file:
@UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? static let kMyDomain = "your domain Name" var backgroundSessionCompletionHandler: (() -> Void)? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { ApplicationDelegate.shared.application(application, didFinishLaunchingWithOptions: launchOptions) TrustKit.setLoggerBlock { (message) in print("TrustKit log: \(message)")} let trustKitConfig = [ // kTSKSwizzleNetworkDelegates: false, kTSKPinnedDomains : [ AppDelegate.kMyDomain : [ kTSKEnforcePinning: true, kTSKIncludeSubdomains: true, kTSKPublicKeyAlgorithms: [kTSKAlgorithmRsa2048], kTSKPublicKeyHashes: [ "public key 1", "public key 2" ], ] ] ] as [String : Any] TrustKit.initSharedInstance(withConfiguration: trustKitConfig)
Step 4: To validate Public Key
After configuration, one can validate the public key by using PinnigValidator and URLSessionDelegate.
static func isServerCertValid(_ challenge: URLAuthenticationChallenge) -> Bool { guard let serverTrust = challenge.protectionSpace.serverTrust else { return false } let pinningValidator = TrustKit.sharedInstance().pinningValidator let trustDecision = pinningValidator.evaluateTrust(serverTrust, forHostname: "myWebsite.com") return trustDecision == .shouldAllowConnection }
Step 5: To test the validation
The easiest way to test the public key pinning is by using Charles Proxy. The Charles Proxy works as a middleman between the application and the server and intercepts the sent requests.
By following the above steps, one can reduce the manual efforts of validating public key and automate this task with TrustKit.