Preventing Man-in-the-Middle Attacks in iOS with SSL Pinning
In this tutorial, you’ll learn how to prevent man-in-the-middle attacks using SSL Pinning and Alamofire. You’ll use the Charles Proxy tool to simulate the man-in-the-middle attack. By Lorenzo Boaro.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Preventing Man-in-the-Middle Attacks in iOS with SSL Pinning
25 mins
- Getting Started
- Understanding TLS
- The Three Phases of TLS Connections
- About Digital Certificates
- The Structure of a Digital Certificates
- Validating Digital Certificates
- SSL Certificate Pinning Under the Hood
- Why Do You Need SSL Certificate Pinning?
- Types of SSL Certificate Pinning
- Pinning in Alamofire 5
- Storing The Certificate
- Implementing Certificate Pinning
- Testing Certificate Pinning With Charles
- Certificate Pinning in Action
- Where to Go From Here?
Nowadays, most iOS apps communicate with a server to retrieve information to work with. When apps exchange information, they typically use the Transport Layer Security (TLS) protocol to provide secure communications.
Apps don’t usually determine which certificates to trust and which not to trust when they try to establish a connection with a server. Rather, they rely entirely on the certificates that iOS contains.
Even if TLS protects the transmitted data against eavesdropping and tampering, attackers can set up man-in-the-middle attacks using hacked or self-signed certificates. Through these certificates, they can capture data moving to and from your app.
In this tutorial, you’ll learn how to prevent man-in-the-middle attacks using SSL Certificate Pinning and Alamofire 5. To verify that your implementation works as expected, you’ll use Charles Proxy‘s man-in-the-middle strategy.
Getting Started
For this tutorial, you’ll use PinMyCert, an iOS app that uses the Stack Exchange REST API to retrieve Stack Overflow users.
Start by downloading the starter project using the Download Materials button at the top or bottom of this tutorial. Once downloaded, open PinMyCert.xcodeproj in Xcode.
To keep you focused, the starter project has everything unrelated to SSL Certificate Pinning already set up for you.
Open Main.storyboard and look at the view controllers contained within. The view controller on the left is the root navigation controller of the app. Next, you have ViewController
, which includes a table that lists the users retrieved from Stack Overflow. Finally, you have DetailViewController
, which displays the detail for the selected user.
ViewController
uses NetworkClient
. This is a wrapper around Alamofire which exposes an API that performs network requests. In NetworkClient
, you’ll implement the logic for dealing with SSL Certificate Pinning. More on that later.
Build and run the app, and you’ll see this initial screen:
Before diving directly into the code, let’s talk about TLS!
Understanding TLS
To understand SSL Certificate Pinning, you should first grasp the essence of TLS and its cryptographic underpinnings.
The main goal of TLS is to add privacy and integrity to messages exchanged between two parties. In other words, TLS allows you to transmit data over a network without exposing that data to untrusted third parties.
When a client and a server need a TLS connection, building that connection follows three phases, executed in a specific order.
The Three Phases of TLS Connections
In the first phase, the client initiates a connection with the server.
The client then sends the server a message, which lists the versions of TLS it can support along with the cipher suite it can use for encryption.
The server responds with the selected cipher suite and sends one or more digital certificates back to the client.
The client verifies that those digital certificates — certificates, for short — are valid. It also verifies that the server is authentic and not someone who wants to snoop sensitive information.
If the validation succeeds, the second phase of verification begins. The client generates a pre-master secret key and encrypts it with the server’s public key — i.e., the public key included in the certificate.
The server receives the encrypted pre-master secret key and decrypts it with its private key. The server and client each generate the master secret key and session keys based on the pre-master secret key.
That master secret key is then used in the last phase to decrypt and encrypt the information that the two actors exchange.
About Digital Certificates
As you’ve learned in the previous section, the server sends one or more certificates back to the client.
So, what’s a certificate? A certificate is a file that encapsulates information about the server that owns the certificate. It’s similar to an identification card, such as a passport or a driver license.
A Certificate Authority (CA) can issue a certificate or it can be self-signed. In the first case, the CA must validate the identity of the certificate holder both before it issues the certificate and when your app uses the certificate. In the second case, the same entity whose identity it certifies signs the certificate.
The Structure of a Digital Certificates
The structure of a certificate uses X.509 standard. Here are the main fields:
- Subject: Provides the name of the entity (computer, user, network device, etc.) that the CA issued the certificate to.
- Serial Number: Provides a unique identifier for each certificate that a CA issues.
- Issuer: Provides a unique name for the CA that issued the certificate.
- Valid From: Provides the date and time when the certificate becomes valid.
- Valid To: Provides the date and time when the certificate is no longer considered valid.
- Public Key: Contains the public key of the key pair that goes with the certificate.
- Algorithm Identifier: Indicates the algorithm used to sign the certificate.
- Digital Signature: A bit string used to verify the authenticity of the certificate.
The couple consisting of the public key and the algorithm identifier represents the subject public key info.
X.509 certificates can be encoded differently, which will affect their appearance. The most common are:
- Privacy Enhanced Mail (PEM): A Base-64 encoding, whose file extension is .pem.
- Distinguished Encoding Rules (DER): A binary encoding, whose file extensions are .cer, .der and .crt.
- Public Key Cryptography Standards (PKCS): Used to exchange public and private objects in a single file. Its extensions are .p7b, .p7c, .p12, .pfx etc.