D
NetworkingHard50 XP4 min read

What is certificate pinning and how do you implement it in Flutter?

TL;DR: Certificate pinning rejects connections to servers whose SSL certificate doesn't match an expected fingerprint. It prevents man-in-the-middle attacks. Implement by setting a custom badCertificateCallback or providing trusted certificates to Dio's HttpClientAdapter.

Full Answer

By default, Flutter trusts any certificate signed by a trusted CA. An attacker with a CA-signed certificate can intercept your traffic. Pinning ties your app to a specific certificate or its public key hash.

Implementation Approaches

  • Certificate pinning: Bundle the server's .pem file in assets, validate against it
  • Public key pinning: Hash the certificate's public key — survives certificate renewal
  • dio_certificate_pinning package: Simpler API wrapper around the same approach
⚠️

Certificate pinning blocks legitimate certificate renewals if you forget to update the app. Use public key pinning instead, and always have a backup pin for certificate rotation.

Code Examples

dartCertificate pinning with Dio + custom HttpClient
Output
// Connection rejected if certificate doesn't match
// Use rootBundle to load pinned cert from app assets

Common Mistakes

  • Pinning in debug builds — breaks Charles Proxy and mitmproxy for development
  • Only pinning the leaf certificate — pin the intermediate CA to survive cert renewal

Interview Tip

💡

Show you know the difference between certificate pinning (exact match) and public key pinning (hash match). Public key pinning is recommended for production because certificates rotate but public keys don't.

#certificate-pinning#security#ssl#man-in-the-middle