Certificate Pinning Implementation for Mobile Apps

Certificate Pinning Implementation for Mobile Apps Apps are intercepted via Charles Proxy or Frida — reading requests, modifying responses, studying the API. This happens because TLS connections validate certificates against system CAs, and the user (or pentester) simply added their own CA as tru

Development and support of all types of mobile applications:

Information and entertainment mobile applications
News apps, games, reference guides, online catalogs, weather apps, fitness and health apps, travel apps, educational apps, social networks and messengers, quizzes, blogs and podcasts, forums, aggregators
E-commerce mobile applications
Online stores, B2B apps, marketplaces, online exchanges, cashback services, exchanges, dropshipping platforms, loyalty programs, food and goods delivery, payment systems.
Business process management mobile applications
CRM systems, ERP systems, project management, sales team tools, financial management, production management, logistics and delivery management, HR management, data monitoring systems
Electronic services mobile applications
Classified ads platforms, online schools, online cinemas, electronic service platforms, cashback platforms, video hosting, thematic portals, online booking and scheduling platforms, online trading platforms

These are just some of the types of mobile applications we work with, and each of them may have its own specific features and functionality, tailored to the specific needs and goals of the client.

Our competencies:

Frequently Asked Questions

Latest works

  • image_mobile-applications_feedme_467_0.webp
    Development of a mobile application for FEEDME
    895
  • image_mobile-applications_xoomer_471_0.webp
    Development of a mobile application for XOOMER
    782
  • image_mobile-applications_rhl_428_0.webp
    Development of a mobile application for RHL
    1216
  • image_mobile-applications_zippy_411_0.webp
    Development of a mobile application for ZIPPY
    1079
  • image_mobile-applications_affhome_429_0.webp
    Development of a mobile application for Affhome
    1002
  • image_mobile-applications_flavors_409_0.webp
    Development of a mobile application for the FLAVORS company
    597

Certificate Pinning Implementation for Mobile Apps

Apps are intercepted via Charles Proxy or Frida — reading requests, modifying responses, studying the API. This happens because TLS connections validate certificates against system CAs, and the user (or pentester) simply added their own CA as trusted. Over the last 5 years, we implemented Certificate Pinning for 30+ mobile projects — from fintech startups to enterprise solutions. This completely closes the MITM attack vector on non-rooted devices. We configure pinning on iOS and Android, including backup pins and CI checks. Timelines range from 2 to 5 days depending on the number of hosts. Want to evaluate your project? Simply contact us.

Why public key pinning is better than certificate pinning

Certificate pinning — the client stores the full certificate (or its SHA-256 hash) and compares it with what the server sends. The certificate changes on every renewal — every 1-2 years. If you forget to update the pin before rotation, the app stops working for all users simultaneously.

Public key pinning (HPKP-style) — pins the hash of SubjectPublicKeyInfo. When the certificate is renewed, the private key often stays the same, so the pin remains valid. This is the right choice for production. Additionally, maintain a backup pin — hash of a backup key (could be from your CA). Let's compare the approaches:

Characteristic Certificate Pinning Public Key Pinning
Client update frequency Every 1-2 years Every few years
Risk of blocking users High Low
Implementation complexity Low Medium
Flexibility when changing CA Requires update Often not required

How we implement pinning: step-by-step process

Stage Description Duration
Infrastructure analysis Identify all hosts, obtain certificates and public keys 1-2 hours
Hash generation Compute SHA-256 SPKI for each key, including backup pin 30 minutes
Pinning implementation Embed validation in the network layer (TrustKit, OkHttp, Flutter) 1-2 days
CI setup Step to verify that release build includes pinning 1-2 hours
Testing Verify blocking via proxy, test backup pin 1 day
Documentation Rotation procedure and emergency update contacts 1 hour

iOS: NSURLSession + TrustKit

func urlSession( _ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void ) { guard challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust, let serverTrust = challenge.protectionSpace.serverTrust else { completionHandler(.cancelAuthenticationChallenge, nil) return } guard let serverCert = SecTrustGetCertificateAtIndex(serverTrust, 0), let serverKey = SecCertificateCopyKey(serverCert) else { completionHandler(.cancelAuthenticationChallenge, nil) return } let serverKeyData = SecKeyCopyExternalRepresentation(serverKey, nil)! as Data let serverKeyHash = sha256(data: serverKeyData) let pinnedHashes = ["base64encodedSHA256ofSubjectPublicKeyInfo=="] if pinnedHashes.contains(serverKeyHash) { completionHandler(.useCredential, URLCredential(trust: serverTrust)) } else { completionHandler(.cancelAuthenticationChallenge, nil) } } 

For projects with multiple hosts, use TrustKit — configured via Info.plist, supports backup pins and violation reporting.

Android: OkHttp CertificatePinner

val certificatePinner = CertificatePinner.Builder() .add("api.example.com", "sha256/AAAAAAAAA...primaryKeyHash==") .add("api.example.com", "sha256/BBBBBBBBB...backupKeyHash==") .build() val client = OkHttpClient.Builder() .certificatePinner(certificatePinner) .build() 

OkHttp automatically computes SHA-256 of SubjectPublicKeyInfo. On mismatch — SSLPeerUnverifiedException. Get hashes via openssl:

openssl s_client -connect api.example.com:443 -servername api.example.com 2>/dev/null \ | openssl x509 -pubkey -noout \ | openssl pkey -pubin -outform der \ | openssl dgst -sha256 -binary \ | openssl enc -base64 

For Flutter, use the http_certificate_pinning package or a native wrapper via platform channels.

What are the risks of incorrect implementation?

The main operational pain — key rotation. 30+ days before certificate renewal, release an update with a new backup pin, let users update, then rotate the key. If this is not done, the app loses connectivity to the server for all clients. In debug builds, pinning is usually disabled via a BuildConfig.DEBUG flag or a separate flavor. Ensure that the release build in CI is built with pinning — otherwise you lose protection.

Common implementation mistakes
  • Using only one pin — if that key is compromised, emergency update is needed.
  • Storing pins in plain text in the binary — an attacker can extract them via static analysis. Use obfuscation or encryption.
  • No fallback to certificate — if all pins don't match, the app should block the connection, not ignore the error.
  • Key rotation without prior client update — the most common cause of mass outages.

What's included in our work

  • Pinning configuration for all app hosts (iOS + Android, up to 5 hosts included).
  • Backup pin — add hash of a backup key for seamless rotation.
  • CI integration — configure flags to separate debug/release builds.
  • Documentation — description of the pin update procedure and emergency release contacts.
  • Support — for 30 days after implementation, we answer questions and help with the first rotation.

Timelines

Pinning setup for one host with backup pins — 2-3 days. For projects with 3+ hosts — up to 5 days. Pricing is calculated individually, depending on complexity and number of platforms.

Get a consultation: contact us, and we'll estimate timelines for your project. Write to us — we'll evaluate your project in one day.