Encryption

How Certificate Pinning Works

Learn how certificate pinning protects mobile apps and APIs from man-in-the-middle attacks by locking connections to specific certificates or public keys.

Editorial Team ·
9 min read intermediate

Introduction

In 2011, a compromised certificate authority called DigiNotar issued fraudulent certificates for Google, allowing Iranian intelligence services to intercept the Gmail traffic of an estimated 300,000 users. Every victim’s device trusted the fraudulent certificate because DigiNotar was in the OS trust store. Certificate pinning exists precisely to prevent this: an application that pins a certificate or public key will reject any connection using a different certificate — even one signed by a trusted CA. High-profile apps like banking applications, healthcare portals, and payment processors rely on pinning as a last line of defence against CA compromise and corporate SSL-inspection proxies. Understanding how certificate pinning works — and where it fails — is essential for any developer building security-sensitive mobile or server-to-server applications.

What Is Certificate Pinning?

Certificate pinning is the practice of hardcoding one or more trusted certificates or public keys directly into an application, overriding the operating system’s default trust store evaluation. When a TLS connection is established, the application checks the server’s certificate against its pinned set. If the certificate or public key matches, the connection proceeds. If it does not match — even if the certificate is validly signed by a trusted root CA — the connection is rejected.

There are two primary pin types. Certificate pinning stores the full X.509 certificate and validates the entire document including its validity period. Public key pinning (also called SPKI pinning, from Subject Public Key Info) stores only the cryptographic public key — typically as a base64-encoded SHA-256 hash of the SPKI structure. Public key pinning survives certificate renewal as long as the same key pair is reused, making it significantly more operationally practical.

The web standard for this concept was HTTP Public Key Pinning (HPKP), defined in RFC 7469, which let servers send pins via an HTTP response header. Google removed HPKP from Chrome in 2018 after numerous websites accidentally bricked themselves with misconfigured pins. Today, pinning lives primarily in mobile applications rather than web browsers.

How Certificate Pinning Works

The pinning workflow happens at the TLS handshake layer:

  1. Pin storage: During development, the developer extracts the server certificate’s public key or full certificate and encodes it — typically as a SHA-256 hash of the DER-encoded SPKI — and bundles it into the application binary.
  2. Connection initiation: When the app opens a TLS connection, the server presents its certificate chain as usual.
  3. Custom trust evaluation: Instead of delegating trust evaluation entirely to the OS, the application intercepts the TLS handshake and extracts the server certificate’s public key.
  4. Hash comparison: The app computes the SHA-256 hash of the server’s SPKI and compares it against each stored pin.
  5. Accept or reject: If any pin matches, the connection proceeds. If no pin matches, the connection is terminated regardless of whether the certificate is otherwise valid.
  6. Backup pins: A well-implemented pinning strategy includes at least one backup pin — the hash of a backup key pair or the CA’s intermediate key — so the app can continue working during a certificate rotation without requiring an emergency app update.
Certificate pinning intercepts the standard TLS trust evaluation and adds a comparison against bundled pins. A valid CA-signed certificate from the wrong key pair is rejected just as firmly as a self-signed one.
Hussein Nasser explains SSL/TLS certificate pinning from first principles — watch particularly how he demonstrates the difference between the standard CA-trust model and what pinning adds on top of it.

Certificate Pinning vs HPKP vs Certificate Transparency

FeatureStatic App PinningHTTP Public Key Pinning (HPKP)Certificate Transparency (CT)
ScopeMobile / native appsWeb browsers (deprecated)All TLS certificates
Where pins are storedApp binaryHTTP response headerAppend-only public CT logs
Protects against rogue CAYesYes (was)Yes — detects after issuance
Risk of self-brickingHigh (if pin expires)Very high (max-age up to 1 year)None
Browser supportN/ARemoved from Chrome/FirefoxRequired for all public TLS certs
Response timeImmediate rejectionImmediate rejectionDetection after mis-issuance, not prevention
StatusActive (mobile)Deprecated (RFC 7469)Mandatory (CAB Forum since 2018)

Certificate Transparency is not a replacement for pinning — it detects mis-issued certificates after the fact through public audit logs, whereas pinning prevents the fraudulent connection in the first place. Understanding Certificate Transparency: How CT Logs Stop Bad TLS Certs will show you how these two defences complement each other in a layered security model.

Real-World Use Cases

Mobile banking apps: Banking apps are the canonical pinning use case. A user connecting from a hotel Wi-Fi network may be subject to a captive portal with SSL inspection. Without pinning, the bank’s app would trust the proxy’s certificate just as it trusts the bank’s own certificate. With pinning, the SPKI mismatch terminates the connection before any credentials are transmitted.

Payment SDKs: Payment processors that provide iOS/Android SDKs — such as Stripe and Braintree — implement pinning inside the SDK to protect card data in transit. Even if the integrating app’s developer misconfigures TLS or adds a debugging proxy, the payment SDK maintains its own independent pin check. This aligns with PCI DSS Compliance requirements for protecting cardholder data in transit.

Server-to-server API clients: Microservices calling internal or partner APIs can pin the server’s public key to ensure the connection is never intercepted by a load balancer, reverse proxy, or internal SSL-inspection appliance that lacks the correct certificate. This extends the zero-trust model described in mTLS Explained: Mutual TLS for Zero-Trust APIs with an additional explicit trust assertion.

Common Mistakes to Avoid

Pinning without a backup pin: If you pin only a single certificate and that certificate is revoked or expires before your app is updated, every user running the old app loses service. OWASP’s MASVS requires at least one backup pin in any security-sensitive mobile application. The backup pin is typically the hash of the CA’s intermediate public key, which changes far less frequently than the server certificate.

Pinning the leaf certificate instead of the public key: Leaf certificate pinning fails on renewal because the new certificate is a different document even if it uses the same public key. Pin the SPKI hash instead; it remains valid across renewals as long as you reuse the key pair.

Forgetting to update pins before certificate rotation: If you plan a key rotation — for example, upgrading from RSA 2048 to ECDSA P-256 — the new public key hash must be deployed to the app before the old certificate expires. Certificate rotations and app release cycles must be coordinated. See Encryption Key Rotation: When and How to Rotate Securely for planning guidance.

Blocking legitimate security monitoring: Enterprise mobile device management (MDM) solutions and corporate security tools often use TLS inspection to scan for malware. Pinning blocks this inspection entirely. Define a clear policy for which apps pin and which do not, and document the exception process for corporate-managed devices.

Getting Started

To implement certificate pinning correctly, follow this practical sequence:

First, generate your pins before deployment. Extract the SHA-256 hash of your server’s SPKI using OpenSSL: run the certificate through openssl x509 -pubkey to extract the public key, then compute the base64-encoded SHA-256 hash of the DER-encoded SPKI. Generate a backup pin from your CA’s intermediate certificate at the same time.

Second, use a framework rather than implementing from scratch. On Android, declare pins in the Network Security Configuration XML — this is the official Google-recommended approach that handles the low-level TrustManager logic for you. On iOS, use the TrustKit open-source library, which handles SPKI extraction, pin comparison, and reporting in a well-tested implementation.

Third, implement a pin reporting mechanism. Both TrustKit and the Android Network Security Configuration support reporting URLs — when a pin validation fails, the framework sends a report to your endpoint. Monitor these reports closely during deployment; unexpected pin failures signal either an active attack or a configuration problem you need to address before it causes widespread outages.

Fourth, plan your rotation procedure as part of initial setup. Before you ship, document exactly what steps are required to update pins in the next app release and how long that release takes to propagate to all users. Keep your backup pin current. For a grounding in the broader PKI system that pinning sits on top of, read Public Key Infrastructure (PKI) Explained. Understanding Digital Certificates will also help you work with the SPKI structure you are pinning.

FAQ

Common questions — answered in plain English.

What is certificate pinning?
Certificate pinning is a security technique where an application explicitly trusts only a specific certificate or public key instead of trusting any certificate signed by a root CA in the OS trust store. This prevents attackers who compromise a CA — or install a rogue root — from intercepting the app's traffic.
What is the difference between certificate pinning and public key pinning?
Certificate pinning validates the entire certificate, including validity dates, so it must be updated whenever the certificate is renewed. Public key pinning only validates the cryptographic public key, which can survive certificate renewal as long as the same key pair is reused, making it more operationally flexible.
Does certificate pinning prevent all man-in-the-middle attacks?
Certificate pinning prevents MITM attacks that rely on trusted CA infrastructure — such as corporate SSL inspection proxies or rogue CAs. It does not protect against attacks that compromise the application's own private key, or attacks below the TLS layer such as network-level interception of unencrypted traffic.
Why is certificate pinning controversial?
Pinning can cause app outages if the pinned certificate expires and the app is not updated in time. It also blocks legitimate traffic inspection tools used by enterprise security teams. These operational risks have led Google to remove HPKP from Chrome and Apple to limit static pinning in favor of runtime trust evaluation.
What replaced HTTP Public Key Pinning (HPKP)?
HPKP was deprecated because a misconfigured pin could permanently brick a website. Modern alternatives include Certificate Transparency logs (which detect mis-issued certs) and dynamic pinning using the CAA DNS record. Mobile apps still use static pinning via bundled certificates or SPKIs in frameworks like OkHttp and TrustKit.
How do you implement certificate pinning in a mobile app?
On Android, use the Network Security Configuration XML to specify certificate pins or use OkHttp's CertificatePinner class. On iOS, use TrustKit or implement URLSession delegate methods to validate the server certificate's public key against a bundled SPKI hash. Always include at least one backup pin in case the primary certificate needs emergency replacement.

References

  1. [1]
  2. [2]
  3. [3]
    Android Network Security ConfigurationAndroid Developers (AOSP), 2024
  4. [4]
  5. [5]