What is certificate pinning and when should you use it?
Updated Feb 20, 2026
Short answer
Certificate pinning is the practice of hard-coding which certificate or public key a client will accept for a given host, instead of trusting any certificate signed by any CA in the system trust store. It closes the gap that ordinary TLS leaves open: a compromised, coerced, or locally installed CA can mint a valid certificate for your domain and silently intercept traffic. The cost is operational — a pinned key that rotates without a client update bricks the app.
Deep explanation
Standard TLS validation asks only one question: was this certificate signed by some CA the device trusts? A typical trust store holds well over a hundred root CAs from many jurisdictions, and any one of them can issue a certificate for any domain. That is the weakness pinning addresses.
Three things can be pinned, and the choice matters:
- Certificate pinning — pin the exact leaf certificate. Simplest, but breaks on every renewal, which for a 90-day Let's Encrypt certificate is four times a year.
- Public key pinning — pin the SPKI hash of the public key. Renewal keeps working as long as the key pair is reused. This is the usual recommendation.
- CA pinning — pin an intermediate or root. Most flexible, weakest guarantee, since anything that CA issues is accepted.
// Android / OkHttp — pin the SPKI hash, with a backupval pinner = CertificatePinner.Builder() .add("api.example.com", "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=") // current .add("api.example.com", "sha256/BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB=") // backup .build()The backup pin is not optional. Pin a single key and you have created a single point of catastrophic failure: lose that private key, or need an emergency rotation, and every deployed client rejects your server until they all update. With mobile apps that can take weeks, and users who never update are permanently broken. Always pin at least one offline backup key.
Where pinning belongs. Mobile and desktop apps talking to your own backend — you control both ends and can ship updates. Financial, healthcare, and messaging clients where a state-level adversary with CA access is a realistic threat.
Where it does not. Public websites, where HPKP (the browser header version) was so dangerous — a misconfigured pin could render a domain unreachable for the pin's lifetime — that Chrome removed support entirely in 2018. Browsers now rely on Certificate Transparency instead, which detects mis-issuance after the fact rather than preventing it. Also avoid it for third-party APIs whose rotation schedule you do not control.
Real-world example
A banking app on a corporate network where IT has installed its own root CA on every device for traffic inspection:
Without pinning: app -> corporate proxy (presents cert signed by corporate CA) -> device trusts the corporate CA -> handshake succeeds -> proxy reads and can modify every request
With SPKI pinning: app -> corporate proxy (cert signed by corporate CA) -> chain is valid, BUT the public key hash does not match the pin -> connection refusedThe same mechanism blocks a user running mitmproxy with a locally trusted root — which is why pinning also frustrates security researchers and your own QA team, and why builds usually disable it outside production.
Common mistakes
- - Pinning a single key with no backup, so an emergency rotation or a lost key bricks every deployed client.
- - Pinning the leaf certificate rather than the public key, guaranteeing breakage at every renewal.
- - Shipping a pin whose expiry outlives the release cadence — clients that stop updating eventually fail permanently.
- - Using HPKP headers on a website
- the mechanism is deprecated and removed from browsers precisely because misconfiguration was unrecoverable.
- - Pinning a third-party API you do not control, then discovering they rotated keys with no notice.
- - Assuming pinning replaces certificate validation — expiry, hostname, and revocation must still be checked.
Follow-up questions
- Why pin the public key rather than the certificate?
- Why was HPKP deprecated in browsers?
- How does Certificate Transparency differ from pinning?
- How do you rotate a pinned key safely?