Certificate Pinning in Mobile and Desktop Applications
Implement HPKP, TrustKit-style pinning, and understand the operational risks of pinning.
Certificate Pinning in Mobile and Desktop Applications is a free Cryptology Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Cryptology Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Why Certificate Pinning Exists
Standard TLS trusts any certificate signed by any of ~150 root CAs pre-installed in the OS. If any root CA is compromised or coerced, an attacker can obtain a certificate for any domain and intercept TLS traffic. Certificate pinning restricts trust to a specific certificate or public key, regardless of which CA signed it. A pinned application rejects connections to its servers unless the server presents the exact expected certificate or key. This protection is particularly valuable for mobile apps where users cannot inspect network traffic and corporate MDM solutions may install enterprise CA roots.
Pin Types: Certificate vs Public Key vs SPKI
There are three granularities of pinning: (1) Full certificate pin — the exact DER-encoded certificate must match. This is the most brittle: it breaks on any certificate renewal. (2) Public key pin — only the SubjectPublicKeyInfo (SPKI) bytes are compared. Survives certificate renewal if the same key pair is retained. (3) Hash of SPKI — store SHA-256(SPKI) rather than the raw key. This is the HTTP Public Key Pinning (HPKP) and Android Network Security Config approach. Public key / SPKI pinning is preferred: it survives CA rotation and certificate renewal while still detecting MITM with a different key pair.
Android Network Security Config
Android (API 24+) provides a declarative pinning mechanism via Network Security Config XML. The file res/xml/network_security_config.xml specifies pins per domain: pin-set with digest="SHA-256" and the base64-encoded SPKI hash. The app references this file in AndroidManifest.xml via android:networkSecurityConfig. Android enforces pins for all HTTP connections made through the standard HttpsURLConnection and OkHttp (when using the platform trust manager). The pin-set requires at least one backup pin (a different key or CA pin) to prevent lockout if the primary key is compromised. Pin expiry (expiration attribute) forces apps to update before pins become stale.
iOS / macOS Certificate Pinning
iOS apps implement pinning in NSURLSession delegates. The URLSession(_:didReceive:completionHandler:) delegate method receives the server trust object. The app calls SecTrustEvaluateWithError to validate the chain, then extracts the leaf certificate with SecTrustGetCertificateAtIndex(trust, 0), exports its SPKI bytes, hashes them with SHA-256, and compares against the stored pin. TrustKit (open source library) wraps this pattern with configuration-based pinning, supporting multiple pins, subdomain matching, and report-only mode. Apple's App Transport Security (ATS) is separate from pinning — ATS enforces TLS version minimums but does not pin keys.
HPKP: HTTP Public Key Pinning (Deprecated)
HTTP Public Key Pinning (HPKP, RFC 7469) attempted to add pinning for web browsers via HTTP response headers: Public-Key-Pins: pin-sha256="base64=="; max-age=5184000; includeSubDomains. The browser would remember the pin for the max-age duration and reject connections to mismatched keys. HPKP was deprecated by Chrome in 2017 and removed in 2019 due to catastrophic failures: a single misconfiguration or key loss could permanently lock users out of a website with no recovery path. HPKP is now effectively dead for web browsers; application-level pinning in mobile apps remains viable because app updates can ship new pins.
Pinning in OkHttp
OkHttp (widely used on Android) supports pinning via CertificatePinner: CertificatePinner.Builder().add("api.example.com", "sha256/AAAA...==", "sha256/BBBB...==").build(). The second pin is the backup. OkHttp verifies that at least one pin matches any certificate in the server's chain — leaf, intermediate, or root. This allows pinning to an intermediate CA (surviving leaf cert rotation) or pinning the root CA (surviving intermediate rotation). OkHttp throws an SSLPeerUnverifiedException with a helpful message listing the server's actual SPKI hashes, making pin extraction during development straightforward.
Bypassing Pinning: Attacker Techniques
Pinning raises the bar for traffic interception but is not unbreakable. Common bypass techniques on mobile: (1) Frida hooks — inject JavaScript into the app process to hook the pin verification method and return true unconditionally. (2) SSLUnpinning tools — automated Frida/Objection scripts targeting common pinning libraries (TrustKit, OkHttp, native SecTrust). (3) Custom ROM — root the device and modify the TLS stack. (4) Repackaging — decompile the APK, modify pinning config, repackage with a new certificate. (5) Memory patching — patch the verification bytecode at runtime. Mitigations: root/jailbreak detection, code obfuscation, integrity checks (SafetyNet/App Attest).
Backup Pins and Disaster Recovery
The biggest operational risk of certificate pinning is self-lockout: if the production key is lost or the certificate expires and the backup is unavailable, users are locked out until an app update ships (days to weeks). Best practices: (1) Always pin at least two keys — the current key and a pre-generated backup key stored offline (HSM or air-gapped). (2) Set a pin expiry date and ship app updates before expiry. (3) Monitor pin failures via report-only mode before enforcing. (4) Maintain an emergency app update pipeline (expedited review) for pin rotation incidents. (5) Pin at the intermediate CA level, not the leaf, to allow leaf cert rotation without app updates.
Desktop Application Pinning
Desktop applications written in Electron, Qt, or native code can implement pinning using their TLS stack APIs. Electron apps use the app.on("certificate-error") event and session.setCertificateVerifyProc() to implement custom verification. Qt network code uses QSslSocket with a custom verification callback. .NET applications use ServicePointManager.ServerCertificateValidationCallback. Native Windows apps use WinHTTP with manual certificate inspection. Desktop applications face additional challenges: OS-level TLS interception via corporate proxies is common, and users may expect proxy functionality to work — requiring a policy decision on whether pinning applies only to specific endpoints.
Pinning in CI/CD and Automated Testing
Certificate pinning complicates automated testing and CI/CD pipelines. Integration tests that make real HTTPS calls to staging servers must use test certificates whose SPKI hashes are pinned in a test configuration. Approaches: (1) Build flavors — the debug/staging build includes staging server pins; release build pins production. (2) Network Security Config overrides — Android allows debug-only pin configuration. (3) Mock server — intercept at the HTTP client layer before TLS, bypassing pinning entirely. (4) Self-signed CA for CI — issue test certificates from a CI CA whose root is trusted only in test builds. Never ship a build with pinning disabled in production.
Post-Quantum Considerations for Pinning
Certificate pins are typically hashes of RSA or EC public keys. When post-quantum migration begins, servers will transition to ML-DSA (CRYSTALS-Dilithium) or hybrid keys. Pinned SPKI hashes will change because the key type and encoding change. Apps pinning leaf certificates or public keys will need coordinated updates: (1) Ship a new app version with the post-quantum SPKI hash as a backup pin before server migration. (2) Complete server migration. (3) Ship an update removing the old classical pin. The transition window requires careful coordination. Apps pinning intermediate or root CAs will be less affected — only the CA's key changes, not necessarily on the same timeline as leaf certificates.
Certificate Pinning Quiz
Why is pinning the SubjectPublicKeyInfo (SPKI) hash preferred over pinning the full certificate?
Certificate Pinning Recap
Certificate pinning restricts TLS trust to a specific certificate or public key, protecting against CA compromise and MITM. SPKI hash pinning (SHA-256 of SubjectPublicKeyInfo) is preferred over full certificate pinning for resilience to renewal. Android uses Network Security Config XML; iOS uses URLSession delegate with SecTrust APIs; OkHttp supports CertificatePinner. Always include a backup pin to prevent self-lockout. HPKP (browser HTTP header) is deprecated. Pinning can be bypassed via Frida hooks and ROM modifications. Post-quantum key migration requires coordinated app updates to update SPKI hashes.
Frequently asked questions
Is the “Certificate Pinning in Mobile and Desktop Applications” lesson free?
Yes — the full text of “Certificate Pinning in Mobile and Desktop Applications” is free to read here on the web, and the Cryptology Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Cryptology Academy course, upgrade to CoddyKit PRO.
What will I learn in “Certificate Pinning in Mobile and Desktop Applications”?
Implement HPKP, TrustKit-style pinning, and understand the operational risks of pinning. You practise Cryptology Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Cryptology Academy?
No prior experience is required. Cryptology Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Certificate Pinning in Mobile and Desktop Applications” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Cryptology Academy lesson?
Yes. Every Cryptology Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- TLS 1.3: 0-RTT, Early Data, and Session Resumption
- Mutual TLS (mTLS) Implementation Patterns
- Certificate Pinning in Mobile and Desktop Applications
- TLS Performance: QUIC and HTTP/3