Certificate Pinning: Trusting Only Your Own Servers
Certificate pinning hardcodes your server's public key hash into your app, rejecting any other certificate. This prevents man-in-the-middle attacks from compromised CAs. The footgun: if the server certificate changes, your app breaks until you update the pin.
WHY IT EXISTS Standard HTTPS/TLS security relies on trusting a large set of Certificate Authorities (CAs) pre-installed on the operating system. If any one of these CAs is compromised, an attacker can issue a fraudulent certificate for your domain, enabling a man-in-the-middle attack that your app would otherwise trust. Certificate pinning was created to prevent this.
THE MENTAL MODEL Think of it as an exclusive allowlist for your server's identity. By default, your app trusts anyone with a valid ID (a certificate from a trusted CA). With pinning, your app only trusts specific individuals whose fingerprints (public key hashes) you've recorded in advance. Even if an attacker shows up with a seemingly valid ID from a compromised CA, if their key's hash doesn't match your list, they are rejected.
HOW IT WORKS During the TLS handshake, the client receives the server's certificate chain. Instead of only verifying the chain up to a trusted root CA, the client also computes the hash (e.g., SHA-256) of the public key in the server's certificate. It then compares this computed hash against a list of "pinned" hashes hardcoded into the application. If the server's key hash matches a pinned hash, the connection is trusted. If no match is found, the connection is immediately terminated, preventing any data exchange.
WHEN TO USE IT Use pinning in high-security applications, like banking or healthcare apps, where the cost of a man-in-the-middle attack is high. It is most effective when you control both the client application and the server infrastructure, as this gives you control over certificate rotation. It specifically protects against a compromised CA, a real threat demonstrated by attacks like the one on DigiNotar.
WHEN NOT TO USE IT Avoid pinning if you lack a strict process for updating your app before server certificates expire or change. If a certificate is renewed and your app doesn't have the new pin, all network requests will fail for users on older versions, effectively locking them out. This brittleness makes it a poor choice for applications where you can't force frequent updates.
ONE CANONICAL EXAMPLE In OkHttp, you use the CertificatePinner to configure pins for specific hostnames. You provide the hostname and a set of SHA-256 hashes of the public keys. A best practice is to pin against an intermediate certificate that you control and to include a backup pin for a future certificate. This allows you to rotate the leaf certificate without breaking older versions of your app.
Read the original → square.github.io
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.