You went and implemented certificate pinning in your app. You tested it, and it worked perfectly.
Fast forward a few months, and your users cannot connect. You haven't changed the code for ages. So, you check your API, and it works fine, but your app? Not so much.
The problem: certificate rotation. Something completely outside your control managed to break your application. Most likely in the most awkward way and at the least desirable or expected time.
What is certificate rotation?
Certificate rotation is the process of replacing an existing certificate with a new one. Certificates require rotation for several reasons:
- Expiration – some certificates expire more often than others (yes, I'm looking at you, Let's Encrypt)
- Revocation – the certificate has been compromised or invalidated
- Algorithm upgrades – moving from SHA-1 to SHA-256, for example
- Domain changes – adding or removing domains from the certificate
Expiration you can plan for. Other rotations are silent, unpredictable. And by the time you notice, users have already noticed. By then, it's too late.
Why does my app break?
Certificate pinning is based on a certificate's public key, hash, trust chain, or other metadata. When the certificate changes, some (if not all) of that data changes too—causing validation to fail.
- Certificate hash and public key change with each new certificate.
- Trust chain changes less frequently, but pinning only the chain is insecure and weak. If you only check the chain, you're effectively accepting any certificate from that chain. And that defeats the purpose of pinning.
What can I do to avoid downtime?
Set expiration reminders.
The easiest thing to do is set up calendar reminders for when your certificates expire. You can't fix what you don't know is expiring.
Pin the SPKI, not the whole certificate.
Some Certificate Authorities (CAs) allow renewal with the same key pair. If you control the server and configure this, the certificate's public key will remain unchanged. But by default, many renewals generate a new key.
Still, pinning the Subject Public Key Info (SPKI) is a decent solution. SPKI is the part of the certificate that contains the actual public key and its algorithm. Pinning this survives renewal if the key pair stays the same.
// Extract SPKI for pinning in .NET
byte[] spki = certificate.GetPublicKey();
string spkiHash = Convert.ToBase64String(SHA256.Create().ComputeHash(spki));
Implement backup pins.
Keep at least two pins: the current certificate and a backup. You can use your CA's root or intermediate certificate for this. When rotation happens, your application still trusts the backup while you update the primary.
Yes, you'll need to refresh the list over time. But your users won't experience downtime.
Get notified before things break.
This is exactly why I'm building CertWatch. The app tracks your certificates and alerts you:
- 90/60/30/14/7/1 days before expiry
- Immediately on unexpected rotation events
The alert includes the new public key, so you can update your pinned app before it breaks. You'll know before your users do.
Conclusion
Certificate pinning makes your app more secure. But without handling rotation, it makes your app brittle and prone to unexpected outages.
Pin SPKI, keep backups, and set reminders. Do that, and you won't be waking up to a bunch of angry emails and calls in distress
