Back to Blog
Security
June 15, 20254 min readby DexGh0st

Certificate Pinning: Not Optional for Payment Apps

Why certificate pinning is essential for mobile payment applications and how to implement it correctly.

Why Certificate Pinning Matters

Certificate pinning prevents man-in-the-middle attacks by verifying that your app only communicates with servers presenting specific, known certificates.

Without Pinning

Attackers can:

  • Intercept all network traffic
  • Steal credentials and payment data
  • Modify transactions in transit
  • Inject malicious responses

PCI DSS Requirement

PCI DSS 4.2.1 requires:

Strong cryptography is used to safeguard sensitive data during transmission

Certificate pinning is a critical control for meeting this requirement.

Implementation Guide

Android (OkHttp)

val certificatePinner = CertificatePinner.Builder()
    .add("api.yourapp.com", "sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=")
    .add("api.yourapp.com", "sha256/BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB=")
    .build()

val client = OkHttpClient.Builder()
    .certificatePinner(certificatePinner)
    .build()

iOS (URLSession)

func urlSession(_ session: URLSession,
                didReceive challenge: URLAuthenticationChallenge,
                completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
    guard let serverTrust = challenge.protectionSpace.serverTrust,
          let certificate = SecTrustGetCertificateAtIndex(serverTrust, 0) else {
        completionHandler(.cancelAuthenticationChallenge, nil)
        return
    }

    // Verify certificate matches pinned hash
    let serverCertData = SecCertificateCopyData(certificate) as Data
    if pinnedCertificates.contains(serverCertData.sha256Hash) {
        completionHandler(.useCredential, URLCredential(trust: serverTrust))
    } else {
        completionHandler(.cancelAuthenticationChallenge, nil)
    }
}

Best Practices

1. Pin Multiple Certificates

Include backup pins:

  • Current certificate
  • Backup certificate
  • Root CA (optional fallback)

2. Plan for Rotation

Certificates expire. Have a plan:

  • Include next certificate before expiry
  • Monitor certificate expiration
  • Force update mechanism

3. Handle Failures Gracefully

When pinning fails:

  • Block the connection
  • Log the attempt
  • Alert security team
  • Don't fall back to unpinned

4. Test Thoroughly

Verify pinning works:

  • Use proxy tools (Charles, mitmproxy)
  • Confirm connections are rejected
  • Test in production-like environment

Verify your certificate pinning implementation. Scan your app.

Newsletter

Get the AppAudix Security Notes

A short mobile app security brief with PCI DSS, OWASP MASVS, Android, and iOS findings.

We verify email ownership before subscribing. No spam.

Share this article

Secure Your Mobile App Today

Automatically scan your Android or iOS app for security vulnerabilities and compliance issues.

Cookie preferences

We use necessary storage for security and login. With your permission, we also use analytics to understand page journeys and marketing pixels to measure ad campaigns.