← Back to blog

Certificate pinning for mobile apps: when and how to do it

October 19, 2026
Certificate pinning for mobile apps: when and how to do it

Certificate pinning makes your mobile app accept a server only if its certificate chain contains a specific, pre-agreed identity, instead of trusting anything a device-trusted certificate authority (CA) has signed. It cuts the risk of man-in-the-middle interception. It also adds an operational risk: if you rotate certificates badly, your app stops connecting. This guide explains how pinning works on Android and iOS, when it earns its place, and how to ship it without locking out your own users.

Pocketapp
Build Security Into Your Mobile App
Pocket App designs, develops and deploys mobile applications, with strategic discovery and cross-platform expertise for businesses across industries.
Explore Pocket App

TL;DR

  • Pinning is an extra layer on top of TLS, not a replacement. The NCSC treats TLS as the baseline and pinning as an additional measure.
  • Pin only endpoints your team controls, and always ship a backup pin. Pinning third-party endpoints is how apps break overnight.
  • Android uses Network Security Configuration. iOS uses NSPinnedDomains in Info.plist. Neither covers every networking path, so inventory your SDKs.
  • Pinning does not stop a determined attacker who controls the device. Pair it with server-side checks and monitoring.
  • Treat it as change management: a rotation runbook, tests and monitoring matter as much as the code.

Table of Contents

What certificate pinning does

Normally, when your app opens a TLS connection, the operating system checks that the server's certificate chains up to a CA it trusts. That is a sound default, but it means any trusted CA can vouch for your domain. If one is compromised or misused, or if a user has installed a malicious root certificate, an attacker can sit between the app and your server and read the traffic.

Pinning narrows that trust. The app carries a preselected certificate or public-key identity, and OWASP describes the result as the app communicating only with remote endpoints that have specific identities. If the chain does not contain the expected identity, the connection fails, even if the certificate would otherwise pass the device's checks.

The failure behaviour matters as much as the check. The NIST Mobile Threat Catalogue says that when server certificate validation fails, the app should not continue negotiating a secure session or fall back to an unencrypted protocol. It should warn the user. A pinned app that quietly retries over HTTP has missed the point.

Is certificate pinning mandatory?

No. Apple's own guidance states plainly that pinning is not required and should be deployed with caution, and only if absolutely necessary. OWASP's testing guidance makes the same point from the other side: pinning can introduce availability risk when server configuration changes, so it should not be applied broadly where the operational risk outweighs the benefit (see the OWASP network communication guide).

The UK position is pragmatic too. The NCSC's application development guidance recommends TLS for sensitive data and lists certificate pinning among the extra steps to make sure the app connects to a host with a known, trusted certificate. It also says a connection showing suspicious secure-channel attributes should be denied until a verified channel is available.

When pinning is worth it

Pinning is easiest to defend when all of these are true:

  • The endpoint is your own API, under your team's control.
  • The app handles credentials, payments, health data or other personal data.
  • You can coordinate certificate or key rotation with app releases.
  • You have a tested way to get a fixed app to users if a pin goes wrong.

When to leave it out

Skip pinning, or pin narrowly, when:

  • The endpoint belongs to a third party. You cannot control their certificate, CA or rotation schedule, so a routine change on their side can break your app.
  • The app only displays public content and carries no sensitive data.
  • Nobody owns certificate lifecycle management on the server side.

That last point is the real test. OWASP's MASWE-0028 entry frames two failure modes: weakness when pinning is implemented incorrectly, and availability failure when it is maintained incorrectly. A technically perfect pin can still be a poor business decision if the team cannot coordinate rotation and releases.

What to pin: certificate, public key or CA

You can pin different things, and the choice decides how often you will have to touch the app.

OptionWhat the app checksResilience to renewalTypical use
Leaf public keyThe key in your server's own certificateLow if keys change at each renewal; fine if you reuse the keyTightly controlled APIs with disciplined key management
Intermediate or CA public keyA key higher up the chainHigher: ordinary renewals under the same CA keep workingMost business apps
Whole certificateThe exact certificate fileLowest: every renewal breaks itRarely recommended

Both platforms favour pinning a hash of the public key (the SubjectPublicKeyInfo) over the full certificate, because the key can survive a certificate renewal. OWASP's iOS guidance distinguishes CA or intermediate pinning, which is generally more resilient to ordinary renewals, from leaf-key pinning, which is narrower and needs more careful rotation.

How to implement certificate pinning on Android

The platform-supported route is Network Security Configuration, an XML file declared in the manifest. You list the domain, then one or more pins. Each pin is a SHA-256 hash of the certificate's SubjectPublicKeyInfo, and at least one pinned key must appear in the server's chain for the connection to succeed.

Three details catch teams out:

  1. Include a backup key. Android's documentation advises it. Without one, a CA or key change can require an app update before connectivity returns.
  2. Pin expiry is a trade-off. Android supports an expiration time for pins, but pinning stops after that date, which gives an attacker a way round it. Use it knowingly.
  3. Coverage has limits. The configuration applies to framework-managed traffic such as HttpsURLConnection and WebView. It does not cover native-code networking or traffic using a custom TrustManager.

If you use Cronet, the approach differs. Public-key pins in CronetEngine.Builder are SHA-256 hashes of the DER-encoded SubjectPublicKeyInfo, and authentication fails if none of the pinned keys is in the host's chain. A backup pin is highly recommended there as well. Cronet also exposes a setting that bypasses local trust anchors, so check how your debug builds, proxies and enterprise TLS inspection behave.

How to implement certificate pinning on iOS

For apps using URLSession and the URL Loading System, Apple documents identity pinning through NSPinnedDomains. It sits under NSAppTransportSecurity in Info.plist. You associate one or more public-key hashes with a domain, and listing more than one key gives you redundancy when credentials rotate.

The boundary to remember is scope. This declarative approach covers URL Loading System traffic. Apps that use the Network framework, raw sockets or third-party SDKs with their own transport need separate controls. OWASP's server trust evaluation page for iOS covers the alternative of evaluating trust in code, and notes pinning can guard against interception even when an attacker controls a CA the device trusts.

So a correct Info.plist is not proof of a pinned app. Security testing has to verify the actual transport path.

Pinning in cross-platform apps

If you build with a cross-platform framework, do not assume a shared abstraction enforces native pinning everywhere. Design the trust policy around the real request paths and SDKs first, then choose the platform mechanism for each. Analytics, crash reporting, maps and payment SDKs often make their own connections. Some should be pinned, some should not, and a few cannot be.

If you are weighing frameworks, our piece on cross-platform app pros, cons and best practices covers the wider trade-offs.

A delivery process that works

This is the sequence we recommend for a bespoke app project:

  1. Classify endpoints and threat model. List every host the app talks to, who controls it and what data crosses the wire.
  2. Confirm the TLS baseline. Standard TLS and hostname validation must be right before pinning adds anything.
  3. Generate and verify pins. Compute SHA-256 hashes of the public key and check them against the live chain.
  4. Add primary and backup pins. Use Android Network Security Configuration or the applicable iOS configuration.
  5. Test properly. Cover success, a wrong-certificate failure, rotation, offline behaviour and upgrade from older app versions.
  6. Monitor and document. Track pin failures after release and write a certificate and key rotation runbook that server and app teams both follow.

The exact implementation depends on the Android API level, the networking library, any native code and the iOS transport APIs. That is why a transport inventory and security acceptance tests belong in discovery and QA, not as a last-minute ticket.

A rotation example

Suppose your API certificate renews every year. You pin the intermediate CA key as primary and keep a second key, generated and stored offline, as backup. Months before the renewal you ship an app version that also pins the key you plan to move to. After most users have updated, you rotate on the server. If you instead rotate first and ship the app later, users on the old version lose connectivity until they update.

App key backup before server certificate rotation

Slow-updating users are the risk here. Check your analytics for how long old versions stay in use before you set a rotation date.

What pinning does not protect against

Pinning is a client-side check, and the client runs on a device the attacker may own. OWASP notes that hooking and dynamic instrumentation can bypass these checks, so pinning should complement server-side authentication, authorisation, token protection, device and app integrity controls and monitoring.

This shows up in practice. Developers have reported penetration testers using Frida to flag a bypassed pinning check in an iOS app, as in this Apple Developer Forums thread. A bypass finding does not mean your implementation was wrong. It means pinning is one layer, and your backend must stay safe when the client is hostile.

For the wider picture, see our guides to mobile app security best practices for UK businesses and encryption and TLS gaps in CI.

Our view: pinning is a process, not a setting

We have delivered more than 300 apps for brands across retail, charity, healthcare and enterprise, and the pattern on security work is consistent. The code for pinning is a few lines. The hard part is everything around it.

We would not add pinning to an app by default. We start in discovery by asking what the app handles and who runs each endpoint. A retail loyalty app with account logins and a healthcare app holding patient information justify a stricter transport policy than a brochure-style app. Where we do pin, we pin endpoints the client controls, we ship backup pins, and we agree a rotation runbook with whoever owns the certificates before launch.

We are also technology-agnostic, so we pick the platform and networking stack that suits the project, then design the trust policy around the real request paths. That avoids the false comfort of a single configuration file that does not cover every SDK.

A pin you cannot rotate safely is a liability. A pin you can rotate in an afternoon, with monitoring behind it, is a good control.

— Paul

Getting pinning right in your next app

If you are commissioning a new app, or inheriting one with unclear security, we can help you decide what to pin and build it into the plan. Our Discover, Design, Develop and Deploy process puts transport and threat-model decisions into discovery, with security testing before release. If you already have an app live and want an expert second opinion, take a look at our Mobile App Clinics. To talk about a project, get in touch.

FAQ

Is SSL pinning mandatory?

No. Apple states that pinning is not required and should be used only if absolutely necessary, and OWASP warns of availability risk. It is best suited to controlled, security-sensitive endpoints where you can manage rotation. TLS with proper validation remains the baseline.

What is the difference between SSL pinning and certificate pinning?

In practice, nothing. The terms are used interchangeably, along with public key pinning and TLS pinning. SSL is the older protocol name, and modern connections use TLS, but the technique is the same: the app checks the server's identity against something it already knows.

What happens if my pinned certificate expires or changes?

If the new chain contains none of your pinned keys, the app refuses to connect. That is why Android and Apple both advise supplying more than one key. With a backup pin already in the shipped app, you can rotate without an emergency release. Without one, users may need to update first.

How do I check whether an app uses certificate pinning?

Start with the configuration: the Network Security Configuration file on Android and the NSPinnedDomains entry in Info.plist on iOS. Then test the real behaviour with a proxy using a certificate the app should reject, because configuration alone does not prove every request path is covered. A security tester can do this as part of a penetration test.

Sources