CertHaloSSL expiry monitoring · by IncubXperts

What is certificate pinning? A practical guide for developers

What certificate pinning is, the kinds of pins, why browsers moved away from it, and how to pin safely now that certificates are renewed more often.

CertHalo team5 min read

When an app or a browser connects over HTTPS, it normally accepts the server's certificate if it was issued by any of the certificate authorities (CAs) the device trusts. Certificate pinning adds one more rule: the client only accepts a certificate (or a public key) it already expects for that server.

Pinning can be a useful extra layer of protection. It is also a common cause of self-inflicted outages, especially now that certificates are renewed more often. This guide explains how it works, where it fits, and how to do it without locking out your own users.

Normal trust, in one paragraph

A device ships with a list of trusted root CAs. A server's certificate is accepted if it chains up to one of those roots, names the right host and hasn't expired or been revoked (more on the chain of trust). Any trusted CA can issue a certificate for any domain, so the client is relying on all of them behaving correctly.

What pinning adds

With pinning, the client also carries a short list of pins: fingerprints of the keys it expects to see for a particular server. After the usual checks pass, it compares the server's certificate chain with that list. If nothing matches, it refuses the connection, even though the certificate is otherwise valid.

The aim is to reduce reliance on the whole CA system for one important connection, for example a banking app talking to its own API.

What you can pin

Pin Accepted when… Trade-off
Leaf certificate The server presents this exact certificate Breaks at every renewal
Leaf public key The certificate carries this public key Survives renewal only if the same key pair is reused
Intermediate or root CA key The chain includes this CA Survives renewals and key changes, but breaks if the CA's intermediates change or you switch CA

Pins are usually a SHA-256 hash of the public key (the certificate's Subject Public Key Info), written in base64. Pinning a key rather than a whole certificate is the common recommendation, because one key can appear in successive certificates.

To see the pin for the key a server presents today:

openssl s_client -connect api.example.com:443 -servername api.example.com </dev/null 2>/dev/null \
  | openssl x509 -pubkey -noout \
  | openssl pkey -pubin -outform der \
  | openssl dgst -sha256 -binary \
  | openssl enc -base64

Why browsers no longer pin websites

Websites could once ask browsers to pin them with an HTTP header (HTTP Public Key Pinning, HPKP). Browsers remembered the pins for weeks or months, so a single mistake, such as a lost key or a change of CA, could lock visitors out with no quick way back. Few sites used it successfully, and major browsers removed support for it around 2019 and 2020.

For public websites, other measures now do this job better (see Alternatives). Pinning is mostly used where one organisation controls both ends of the connection.

Where pinning can make sense

  • Mobile apps calling their own API, where the same team ships the app and runs the servers.
  • Devices and embedded systems that only ever talk to their maker's backend.
  • Internal services inside one organisation.

Even in these cases, platform guidance is cautious: pinning is optional, and the main risk is to availability, not security. Decide on it deliberately, with a plan for updating pins.

How platforms support it

  • Android: the Network Security Configuration file can declare a pin-set for a domain, with SHA-256 pins and an expiration date after which pins are no longer enforced (a built-in safety net).
  • iOS: App Transport Security supports NSPinnedDomains (iOS 14 and later), with leaf or CA public-key pins.
  • HTTP libraries: many clients have pinning built in, for example OkHttp's CertificatePinner on the JVM and Android.

Whichever you use, the pins are compiled into the client, so changing them means shipping an update. Users who don't update keep the old pins.

Pinning and shorter certificate lifetimes

Certificate lifetimes are shrinking: 200 days from March 2026, 100 days from 2027 and 47 days from 2029 (how to prepare). Renewals that used to happen once a year will happen every few weeks, usually automatically. Each one is a moment where a pin can stop matching:

  • A leaf certificate pin fails at every renewal.
  • A leaf key pin fails whenever automation generates a new key, which many tools do by default.
  • A CA pin fails when the CA rotates its intermediates (Let's Encrypt, for example, issues from several intermediates and rotates them) or when you move to another CA.

Pinning safely: a checklist

  1. Pin public keys, not certificates.
  2. Always include a backup pin: the hash of a second key pair you've generated and stored safely but not yet deployed, so you can switch keys without breaking clients.
  3. Prefer pinning at a level you control. If you pin a CA, pin more than one, and know which intermediates your CA uses.
  4. Keep the same key across renewals if you pin the leaf key, and make sure your renewal tooling does that deliberately.
  5. Set an expiry on pins where the platform supports it, so an old app version fails open rather than failing closed forever.
  6. Have a way to update pins without waiting for every user to update, such as a remote configuration your app fetches securely.
  7. Monitor what your servers actually present after every renewal, and before your pins would stop matching.

Alternatives to pinning

For most teams, these give much of the benefit with far less risk:

  • CAA DNS records list which CAs may issue certificates for your domain, so other CAs should refuse.
  • Certificate Transparency monitoring: publicly trusted certificates are logged, and you can watch the logs for certificates issued for your domains that you didn't request.
  • Strong TLS configuration: TLS 1.2 and 1.3 only, a complete chain, and HSTS (turn off old TLS versions).

How CertHalo helps

If you pin, you need to know the moment your certificate changes. CertHalo checks your servers from the outside and alerts you when a certificate is renewed, when its issuer changes, and before it expires, so a renewal never surprises an app with pinned keys. Run a one-off check with the free SSL checker, or monitor 3 certificates free.

Key takeaways

  • Certificate pinning makes a client accept only specific keys for a server, on top of normal CA trust.
  • Browsers dropped pinning for websites; it's now mainly used by apps and devices that talk to their own servers.
  • The main risk is locking out your own users when certificates or keys change, and shorter certificate lifetimes make that more likely.
  • Pin public keys, keep a backup pin, plan how to update pins, and monitor every renewal.

Check your certificate now

See when it expires, who issued it, whether the chain is complete and if it's been revoked. Free, no sign-up.

Want a reminder before it expires? Monitor 3 certificates free.

More from the blog