SSL Pinning: Essence, Mechanism and Protection from MITM Attacks

Author: IT Sectr Published: 2026-03-09 Reading time: 9 min

SSL Pinning is a security technique where the application verifies the server certificate against a pre-known fingerprint or certificate, rather than relying on the CA chain of trust. Unlike standard verification, pinning prevents traffic interception through fraudulent root certification authorities. According to the OWASP Mobile Security Testing Guide (2025), this technique is in the top-3 recommended controls for protection against MITM attacks. Without pinning, an attacker with a fraudulent root certificate can decrypt all HTTPS traffic of the application.

Key Takeaways

  • SSL Pinning — binding an application to a specific certificate or server fingerprint instead of trusting the entire CA chain
  • MITM attacks are prevented by checking the certificate against a whitelist, not through public CAs
  • Two main types — certificate pinning and public key pinning
  • Implementation on iOS requires URLSession delegate, on Android uses OkHttp CertificatePinner or Network Security Config
  • Key rotation is the main challenge: when the certificate changes, the application needs to be updated via backup pins mechanism

What is SSL Pinning?

SSL Pinning is a security mechanism where a mobile or web application remembers a trusted server certificate or public key and rejects any connections whose certificate does not match the stored one. In the standard HTTPS scheme, the client verifies the certificate through a trust chain up to the root CA — any CA can sign a certificate for any domain. SSL Pinning eliminates this weakness: instead of trusting hundreds of CAs, the application trusts only one specific certificate.

The problem with standard verification is that any of hundreds of root CAs can issue a valid certificate for your domain — accidentally or under duress. An attacker who gains access to a corporate proxy with its own root certificate can conduct a MITM attack without browser warning. SSL Pinning closes this vulnerability: even if a CA issues a fraudulent certificate, the application will reject it because the fingerprint does not match the recorded one.

In mobile applications, SSL Pinning is especially important because devices often operate on unsecured networks — public Wi-Fi, corporate proxies with traffic inspection, infected access points. According to the Verizon Mobile Security Index (2025), over 60% of data breaches in mobile applications are related to traffic interception at the transport layer.

Why SSL Pinning is Needed in Mobile Development

Mobile applications transmit sensitive data — authentication tokens, payment information, personal user data. Without additional protection, HTTPS can be compromised through root certificate substitution on the device — for example, after installing a corporate profile or malicious application. SSL Pinning ensures that even if a fraudulent root CA is installed on the device, the application will continue to verify the certificate against its own whitelist.

How Does SSL Pinning Work?

The SSL Pinning process consists of three stages: fingerprint capture, connection verification, and error handling. During development, the engineer obtains the SHA-256 fingerprint of the server certificate (openssl x509 -fingerprint -sha256) and embeds it into the application code or configuration file. With each HTTPS request, the application computes the fingerprint of the received certificate and compares it with the stored one — if the values do not match, the connection is terminated.

The first stage is pinning at build time: the developer knows the server certificates in advance and embeds their hashes. The second stage is pinning on first connection (trust on first use, TOFU): the application remembers the certificate on the first request and uses it to verify all subsequent ones. TOFU is convenient for dynamic environments but is vulnerable on the first attack — if the first connection is already intercepted, the fraudulent certificate will be accepted as trusted.

A critical detail is backup pins. Certificates have an expiration date, and when they are replaced, the application without an update will lose connection to the server. Engineers include 2–3 additional fingerprints — for example, a backup certificate fingerprint and a root CA fingerprint. If the main certificate changes, the application checks against backup pins, and the connection continues to work.

bash
# Obtaining the SHA-256 certificate fingerprint
openssl s_client -connect example.com:443 </dev/null 2>/dev/null | \
  openssl x509 -pubkey -noout | \
  openssl pkey -pubin -outform der | \
  openssl dgst -sha256 -binary | \
  base64

Types of SSL Pinning

There are two main approaches to implementing pinning: certificate pinning (binding to the entire certificate) and public key pinning (binding to the public key). Each approach has its own strengths and limitations that affect security and maintainability.

TypeObject of BindingFlexibilitySecurity
Certificate PinningEntire X.509 certificateLow — requires update when certificate changesHigh — precise binding
Public Key PinningPublic key of the certificateMedium — the key may be in a new certificateHigh — less sensitive to certificate details
Hash PinningSHA-256 hash of certificate or keyHigh — can change certificates without changing the keyMedium — depends on hash strength

Certificate Pinning

Certificate pinning is the strictest method. The application stores a copy of the trusted certificate or its SHA-256 fingerprint and compares it with the server certificate on each HTTPS connection. This method provides maximum security but creates problems during rotation — certificates typically last 1–2 years, after which a forced application update is required. Recommended for critical systems with a controlled update cycle.

Public Key Pinning

Public key pinning is a more flexible approach. Instead of the entire certificate, the application remembers only the server's RSA or ECDSA public key. The key can remain unchanged when the certificate is re-issued, if the company uses the same key pair. This reduces the frequency of application updates. However, if the key is compromised, a cascade replacement on all clients will be required.

SSL Pinning on iOS

On the Apple platform, SSL Pinning is implemented through the URLSession delegate. The developer creates a class implementing the URLSessionDelegate protocol and overrides the didReceive challenge method, where they manually verify the server certificate against stored fingerprints. An alternative approach is using Alamofire with ServerTrustManager, which simplifies configuration.

swift
class SSLPinningDelegate: NSObject, URLSessionDelegate {
    let pinnedHash = "sha256/Wi24BE7j5qLk0iLvPq6ePEsVRqZ1yW0F6wLg="

    func urlSession(_ session: URLSession,
        didReceive challenge: URLAuthenticationChallenge,
        completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {

        guard let serverTrust = challenge.protectionSpace.serverTrust
            else { return completionHandler(.cancelAuthenticationChallenge, nil) }

        if validate(serverTrust, pinnedHash) {
            completionHandler(.useCredential, URLCredential(trust: serverTrust))
        } else {
            completionHandler(.cancelAuthenticationChallenge, nil)
        }
    }
}

In the example, the delegate receives an authentication request from URLSession, extracts serverTrust from the challenge, and compares the SHA-256 fingerprint of the certificate with the stored one. If the fingerprint matches — the connection proceeds, otherwise the challenge is rejected. For production, it is worth adding verification of multiple backup pins and error logging for monitoring.

Network Security Config on iOS

Starting with iOS 14, Apple added built-in support for Certificate Pinning through Info.plist. The developer specifies trusted certificates in the NSAppTransportSecurity key with the NSPinnedDomains sub-dictionary. This approach does not require writing code but is less flexible — it is impossible to dynamically change pins or log verification errors.

SSL Pinning on Android

On Android, there are three main ways to implement SSL Pinning: through the OkHttp library's CertificatePinner, through Network Security Config in XML, and through custom verification in HttpsURLConnection. OkHttp is the most popular and recommended approach, used in Retrofit and other HTTP clients.

kotlin
val certificatePinner = CertificatePinner.Builder()
    .add("api.example.com",
        "sha256/Wi24BE7j5qLk0iLvPq6ePEsVRqZ1yW0F6wLg=")
    .add("api.example.com",
        "sha256/FiPq6ePEsVRqZ1yW0F6wLgWi24BE7j5qLk0iL=")  // backup pin
    .build()

val client = OkHttpClient.Builder()
    .certificatePinner(certificatePinner)
    .build()

In the OkHttp configuration, the developer specifies the domain and one or more SHA-256 fingerprints. On the first fingerprint, OkHttp compares the server certificate with the specified pins. If there is no match, the client throws SSLPeerUnverifiedException. A backup pin is mandatory — without it, when the certificate changes, API requests will immediately start failing.

Network Security Configuration on Android

Android supports declarative Certificate Pinning through XML configuration starting from API 24. The file res/xml/network_security_config.xml contains a list of domains and their fingerprints. This method is convenient for static configurations but does not allow implementing TOFU or custom verification logic with logging of anomalies.

xml
<!-- res/xml/network_security_config.xml -->
<network-security-config>
    <domain-config cleartextTrafficPermitted="false">
        <domain includeSubdomains="true">api.example.com</domain>
        <pin-set expiration="2027-12-31">
            <pin digest="SHA-256">
                Wi24BE7j5qLk0iLvPq6ePEsVRqZ1yW0F6wLg=</pin>
            <pin digest="SHA-256">
                FiPq6ePEsVRqZ1yW0F6wLgWi24BE7j5qLk0iL=</pin>
        </pin-set>
    </domain-config>
</network-security-config>

Pros and Cons of SSL Pinning

SSL Pinning significantly increases the security of a mobile application but introduces operational complexities. The main advantage is protection against MITM attacks even when root CAs are compromised. The application trusts only those certificates explicitly specified by the developer, not the entire infrastructure of public certification authorities. This is especially critical for financial applications, messengers, and applications with sensitive data.

The main drawback is the complexity of certificate rotation. If a certificate expires or is revoked, users without an application update lose connection. This is solved through backup pins and a gradual update mechanism: the new application knows both the old and new certificates, and after a full update of users, the old pin is removed from the code. It is recommended to include at least 2 backup pins — one for the current certificate, one for the future.

Another compromise is the inability to use public proxies for traffic debugging (Charles Proxy, Burp Suite) without disabling pinning. This complicates debugging of network requests during development. The solution is conditional compilation: pinning is disabled in debug builds and enabled in release builds. OWASP recommends using the BuildConfig.DEBUG flag for switching.

AspectAdvantageDisadvantage
SecurityProtection against MITM through fraudulent CAsComplexity when a key is compromised
MaintenanceExplicit trust controlRotation requires application update
DebuggingGuaranteed connection to the correct serverBlocks debugging proxies

Frequently Asked Questions

What is the difference between SSL Pinning and standard HTTPS verification?

Standard HTTPS verification trusts any certificate signed by a known root CA. SSL Pinning trusts only a specific certificate or key — if a CA issues a fraudulent certificate, the application will reject it.

How often should pinned certificates be updated?

Certificates typically last 1–2 years. It is recommended to update pins 3–6 months before the current certificate expires, adding the new fingerprint as a backup pin, and removing the old one after rotation.

Can SSL Pinning be used with a CDN?

Yes, but keep in mind that CDNs may change certificates when switching between edge servers. It is recommended to pin to the public key rather than a specific certificate, and use multiple backup pins.

What happens on an SSL Pinning verification error?

The connection is terminated with an error — on Android this is SSLPeerUnverifiedException, on iOS the challenge is rejected with .cancelAuthenticationChallenge. The application should properly handle this error and notify the user.

Is SSL Pinning mandatory for all mobile applications?

No, but OWASP recommends it for applications handling sensitive data: banking, healthcare, corporate systems. For simple read-only applications, standard HTTPS verification with EV certificates is usually sufficient.

Summary

  • SSL Pinning — binding an application to a specific server certificate or key, eliminating dependence on the CA trust chain
  • Two main types — certificate pinning (strict, bound to the certificate) and public key pinning (flexible, bound to the key)
  • Backup pins — a mandatory element: at least 2 backup fingerprints for smooth certificate rotation
  • iOS — implementation via URLSessionDelegate with manual serverTrust verification or Alamofire ServerTrustManager
  • Android — OkHttp CertificatePinner (programmatic) or Network Security Config (declarative via XML)
  • Risk — with incorrect rotation of pinned certificates, users lose connection until the application is updated
  • Recommendation — use SSL Pinning for applications with financial, medical or corporate data

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also