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 that 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
Top comments (3)
Thanks Vladimir. I dont think pinnig the root or the intermediate is a good idea. I didn't face any issues reusing certificate public key. where did face this?
I ran into this issue with one of my apps. Certificate expired, I had no idea and suddenly users couldn't connect. Fun times.
Also, I agree. Using any sort of root or intermediate certificate isn't ideal from a security standpoint. In practice, though, it is often the difference between an outage and smooth rotation, while you update the primary cert.
As for public keys, I am yet to see a cert reissued or renewed with same public key. And I've been at this for 20 years.
Also, am curious. What approach do you take to avoid certificate rotation issues.
I've used the same public key many times it not the best thing to do thought. As for the approach we use our internal CA and lots of automation around renewal