Skip to Content
Technical Articles
Author's profile photo Marco Eidinger

Certificate Pinning on iOS 14

Do you develop native mobile applications for iOS 14+ and you want to secure your app against man-in-the-middle attacks by enabling certificate pinning?

In this article, I will explain how to leverage the simplified way of certificate pinning that Apple introduced with iOS 14. I will share details on

  1. how to obtain the public key
  2. how to pin public keys
  3. how to verify/test certificate pinning

It is possible to pin one or more keys of

  • Certificate Authority (CA) or sub-CA certificates
  • leaf certificates

As an example, I’ll pin the public key of the leaf certificate associated with SAP Mobile Services (CF, eu10 region). That’s because I am using an app developed with SAP BTP SDK for iOS which allows me to easily use SAP Mobile Services and I only have to worry to protect a single endpoint to which my app connects. The server name in my example is https://mobile-ios-sdk-tango-com-sap-btp-democai.cfapps.eu10.hana.ondemand.com. You can look up your server name on the API tab of your native/hybrid application in the Mobile Services cockpit.

How to obtain the public key

First I have to obtain the public key as the Base64-encoded SHA-256 digest of the X.509 certificate’s DER-encoded ASN.1 Subject Public Key Info structure.

This can be done by a series of openssl commands chained together. I am executing this command in the terminal on my Mac:

openssl s_client -showcerts -servername mobile-ios-sdk-tango-com-sap-btp-democai.cfapps.eu10.hana.ondemand.com -connect mobile-ios-sdk-tango-com-sap-btp-democai.cfapps.eu10.hana.ondemand.com:443 </dev/null 2>/dev/null|openssl x509 -outform PEM | openssl x509 -inform pem -noout -outform pem -pubkey | openssl pkey -pubin -inform pem -outform der | openssl dgst -sha256 -binary | openssl enc -base64

To use similar command for your example you only have to replace is the value following -servername with your specific servername:)

Response: BXqb+rIKJbzS/nO3PX8F8qJsb8jeebWUplOci2Q74So=

How to pin the public key

Let use the new property key list “NSPinnedDomains” which was introduced for the Security framework for iOS 14. It allows developers to specify a collection of certificates that App Transport Security (ATS) expects when connecting to named domains.

Depending on the type of public key you want to pin you will have to specify the value either for the NSPinnedCAIdentitites key or for the NSPinnedLeafIdentities key.

As I am pinning the public key of a leaf certificate I am using the Base64-encoded value (BXqb+rIKJbzS/nO3PX8F8qJsb8jeebWUplOci2Q74So=) and I am changing the Info.plist of my Xcode project:

	<key>NSAppTransportSecurity</key>
	<dict>
        <key>NSPinnedDomains</key>
            <dict>
                <key>mobile-ios-sdk-tango-com-sap-btp-democai.cfapps.eu10.hana.ondemand.com</key>
                <dict>
                    <key>NSIncludesSubdomains</key>
                    <true/>
                    <key>NSPinnedLeafIdentities</key>
                    <array>
                        <dict>
                            <key>SPKI-SHA256-BASE64</key>
                            <string>BXqb+rIKJbzS/nO3PX8F8qJsb8jeebWUplOci2Q74So=</string>
                        </dict>
                    </array>
                </dict>
            </dict>
	</dict>

 

How to test

My app, generated with the SAP BTP SDK Assistant for iOS, connects exclusively with SAP Mobile Services running on the Cloud Foundry environment in region eu10 (Frankfurt, Europe). I am able to verify certificate pinning by using a Proxy tool. In my case, I choose Charles Proxy. Once I enabled SSL Proxying iOS will detect this man-in-the-middle attack and will refuse the connection.

See video https://youtu.be/IK5dD921zaQ for details.

Recommendation by Apple: pin public keys of CAs

Your app can proactively provide a great experience by pinning the public keys of CAs, instead of servers. This way, you can deploy server certificates that contain new public keys signed by the same CA without the need for pinning configuration updates.

You can also consider pinning more than one public key, especially when pinning server identities. This way, your app will still be able to connect to configured servers even if they revoke or rotate certificates.

Source

The fingerprints for the root CA certificates trusted by SAP trust center are shared here.

Conclusion

It is very simple to enable certificate pinning for apps running on iOS 14 and above.

You can read more about Identity Pinning: How to configure server certificates for your app which was published by Apple on January 14, 2021

Happy Pinning!

Assigned Tags

      1 Comment
      You must be Logged on to comment or reply to a post.
      Author's profile photo Fabiano Rosa
      Fabiano Rosa

      Hi Marco,

      Great blog post that shows how to use the iOS security features to ensure security for enterprise mobile applications, congratulations!

      Regards,

      Fabiano Rosa