Certificate Pinning is a security technique where a mobile application verifies that the server’s certificate matches a pre-known sample, rather than simply trusting any certificate from the CA chain. Unlike regular TLS verification, which relies on hundreds of certificate authorities, pinning narrows trust to a single specific certificate or its public key. According to the OWASP Mobile Security Testing Guide (2024), implementing Certificate Pinning blocks 100% of Man-in-the-Middle attack scenarios involving certificate substitution. OWASP MSTG, 2024
Key Takeaways
Certificate Pinning is a security mechanism where the application stores (or “pins”) a sample of the server’s certificate and compares the received certificate against this sample on each connection. If the certificate does not match — the connection is terminated, even if it is officially signed by a trusted certificate authority. This protects against attacks where an attacker obtains a fake certificate through a compromised CA (as happened with DigiNotar in 2011 or Comodo in 2011).
The pinning process consists of three stages: extracting a fingerprint of the certificate or public key from a trusted instance; storing this fingerprint in the application code or resources; comparing during the TLS handshake. The developer can pin the SHA-256 fingerprint of the entire certificate or just the public key (Public Key Pinning). The second approach is preferable: when the certificate is renewed, the public key often remains the same, and the app does not lose connection to the server. According to OWASP recommendations, the minimum number of pins is 2: one current and one backup for key rotation. Modern libraries such as OkHttp and TrustKit automate the process of checking specified pins during each TLS connection without additional developer effort. It is important to understand that pinning does not replace standard TLS verification, but complements it: first, a regular handshake with certificate chain validation is performed, then an additional pinning check. This two-level protection eliminates vulnerabilities related to CA compromise, including cases of erroneous certificate issuance and attacks on certificate authority infrastructure.
There are several approaches to implementing Certificate Pinning, each with its own storage and verification characteristics. The choice of method depends on the application architecture, certificate update frequency, and flexibility requirements.
| Pinning Type | What Is Stored | Flexibility | Usage Example |
|---|---|---|---|
| Certificate Pinning | Entire X.509 certificate | Low | Fixed certificate for 1–2 years |
| Public Key Pinning | Public key (SPKI) | Medium | OWASP recommended approach |
| Hash Pinning | SHA-256 fingerprint | Medium | Popular in OkHttp (certificatePinner) |
| CA Pinning | Intermediate CA | High | Enterprise applications |
The most balanced method is Public Key Pinning, recommended by OWASP and Google. Instead of a specific certificate (which changes every 1–2 years), the application stores the SubjectPublicKeyInfo fingerprint — an abstraction of the public key. If the certificate is renewed with the same key (key reuse), the pin remains valid. If the key changes — the developer adds a backup pin in the application update in advance. In mobile projects, a min/max pins strategy is used: minimum 2 pins including backup, and maximum 4 to prevent bloat and increased verification time.
The choice of a specific pinning type depends on the application architecture and requirements. For public mobile applications working with REST API through a single domain, Public Key Pinning with two pins via OkHttp or TrustKit is optimal. For enterprise applications with their own certificate authority, CA Pinning is suitable — it does not require updates when client certificates change, as trust is tied to the CA, not the end certificate. For IoT and embedded systems, Certificate Pinning with full certificate pinning is recommended: devices are rarely updated, so control over the entire trust chain is critical. Monitoring pin expiry dates is mandatory practice: set alerts 30, 14, and 7 days before the certificate expires to release an application update with new pins before the current certificate becomes invalid. For automating the release of updates with new pins, it is recommended to use Firebase Remote Config or a custom configuration API that allows dynamically updating the pin list without publishing a new version in the app store.
Certificate Pinning significantly increases mobile application security but places an operational burden on the development team. It is important to weigh the security benefits against the risks of connection blocking due to incorrect implementation.
The main advantage is protection against Man-in-the-Middle attacks, including cases of CA compromise. Pinning makes fake certificates issued by an attacker useless: even if a CA signed a forgery, the application will reject it. An additional benefit is protection against corporate proxy servers that substitute certificates for traffic inspection. According to Google Security Blog (2023), applications with pinning have 86% fewer chances of being compromised through traffic interception compared to applications using only standard TLS verification.
The main disadvantage of pinning is the risk of self-blocking: if the server certificate changes (renewal, provider change, key rotation) before the application update is released, users lose access to the server. Additional drawbacks: debugging complexity (every configuration change requires pin updates), APK size increase by 5–15 KB when using TrustKit, and the inability to quickly roll back changes without a new release. To minimize risks, backup pins, automatic rotation every 2–3 months, and a grace period are used, during which the application accepts both the old and new certificate. It is also important to consider that during development with pinning enabled, proxy tools (Burp Suite, Charles) cannot be used for debugging network requests — for dev builds, pinning must be disabled via the BuildConfig.DEBUG flag, and QA testing should be performed on the release signature with protection enabled. Some teams use a staging domain with a separate pinning certificate for the dev environment to maintain protection even during development.
Let’s look at an example of implementing Certificate Pinning on Android using OkHttp — the standard library for network requests. OkHttp provides a built-in CertificatePinner that accepts SHA-256 hashes of public keys.
val certificatePinner = CertificatePinner.Builder()
.add(
"api.example.com",
"sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
)
.add(
"api.example.com",
"sha256/BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB="
)
.build()
val client = OkHttpClient.Builder()
.certificatePinner(certificatePinner)
.build()
In the code above, we add two pins for the domain api.example.com: the primary (current certificate) and a backup pin (for rotation). OkHttp automatically verifies that the server’s certificate matches one of the specified SHA-256 fingerprints. To obtain the SHA-256 certificate fingerprint, use the command: openssl s_client -connect api.example.com:443 | openssl x509 -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | base64. It is important to store fingerprints not as plain text in the code, but encrypted or obfuscated: MobSF static analysis easily finds raw SHA-256 strings in DEX files. It is recommended to store pins in res/raw resources, encrypted via AES, and decrypt them at application startup through native code (NDK/JNI).
On iOS, the primary tool for Certificate Pinning is the open-source TrustKit library. Unlike OkHttp, TrustKit is configured declaratively through Info.plist, allowing pin changes without recompiling the application. The configuration includes a dictionary with domains and an array of SHA-256 public key fingerprints. TrustKit automatically intercepts NSURLSession requests and verifies certificates before data transmission begins. A critical feature of TrustKit is support for pin validation reports: the library can send reports to a specified endpoint when a pin mismatch occurs, enabling rapid response to certificate anomalies. Apple also provides a native NSPinnedDomains mechanism in Info.plist starting from iOS 14, but TrustKit remains the preferred choice due to more flexible configuration, report support, and the ability to hot-swap pins without OS updates. It is important to note that TrustKit integrates with URLSession via the didReceiveChallenge delegate, returning .performDefaultHandling upon successful pin verification and .cancelAuthenticationChallenge on mismatch. For monitoring pin validation reports, it is recommended to set up a separate endpoint that analyzes error frequency: if the number of reports sharply increases — this may indicate a MitM attack or imminent certificate expiration requiring immediate pin updates.
Frequently Asked Questions
Certificate Pinning is like saving a friend’s fingerprint in your phone: you remember what the “correct” server certificate looks like, and you don’t trust anyone else, even if someone shows identification from an “official” authority.
Regular HTTPS trusts any certificate signed by any CA among hundreds of authorities. Certificate Pinning adds a check on top: the certificate must not just be valid, but specifically the one you hardcoded in the application code.
It is recommended to store 2–3 pins: the current one and a backup pin for the new certificate. 1–2 months before the certificate change, release a new version of the application with the future certificate’s pin added. After the change, the old pin is removed from the next release.
Yes, it can. Pinning works with any certificates, including Let’s Encrypt. It is important to remember that free certificates have a short validity period (3 months), so a backup pin strategy and automatic rotation become mandatory.
Use Burp Suite or mitmproxy for testing pinning. If the application with pinning is configured correctly, the proxy tool will not be able to intercept traffic — the connection will be terminated at the handshake stage. For integration tests, use OkHttp’s MockWebServer.
Summary
We will develop a mobile application turnkey
IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.
Read also