Docs / Security / How to Set Up Certificate Pinning for HTTPS

How to Set Up Certificate Pinning for HTTPS

By Admin · Mar 15, 2026 · Updated Apr 23, 2026 · 175 views · 2 min read

Certificate pinning (also known as HTTP Public Key Pinning) associates a specific cryptographic public key with a server, preventing man-in-the-middle attacks even if a Certificate Authority is compromised. While traditional HPKP is deprecated, modern alternatives exist.

Why Certificate Pinning?

  • Protects against compromised or rogue Certificate Authorities
  • Prevents MITM attacks using fraudulent certificates
  • Adds an extra layer of trust validation beyond standard PKI

HPKP Is Deprecated

HTTP Public Key Pinning (HPKP) via headers was deprecated by browsers in 2018 because misconfiguration could permanently lock users out of a website. Modern alternatives include:

Certificate Transparency (CT)

# Certificate Transparency logs all issued certificates publicly
# Browsers now require CT compliance for all certificates
# This makes rogue certificate issuance detectable

# Check if your certificate is logged:
# https://crt.sh/?q=yourdomain.com

# Expect-CT header (monitoring mode)
add_header Expect-CT "max-age=86400, enforce" always;

CAA DNS Records

# CAA records specify which CAs can issue certificates for your domain
# This prevents unauthorized CAs from issuing certificates

# Allow only Let's Encrypt to issue certificates
yourdomain.com. IN CAA 0 issue "letsencrypt.org"
yourdomain.com. IN CAA 0 issuewild "letsencrypt.org"
yourdomain.com. IN CAA 0 iodef "mailto:security@yourdomain.com"

# Verify CAA records
dig yourdomain.com CAA

Application-Level Pinning

# For mobile apps and API clients, pin the certificate in code:

# Python requests with pinning
import requests
import hashlib
import ssl

def verify_pin(conn, cert, errno, depth, ok):
    # Extract public key hash
    der = ssl.DER_cert_to_PEM_cert(cert)
    digest = hashlib.sha256(cert).digest()
    expected = b"your_expected_pin_hash"
    return digest == expected

# curl with pinning
curl --pinnedpubkey "sha256//YourBase64EncodedHash=" https://yourdomain.com

Monitoring for Unauthorized Certificates

# Set up certificate transparency monitoring
# Services that alert you when new certificates are issued:
# - crt.sh (manual checking)
# - Certspotter (certspotter.com)
# - Facebook CT Monitor
# - SSLMate (sslmate.com/certspotter)

Best Practices

  1. Use CAA DNS records to restrict certificate issuance
  2. Monitor Certificate Transparency logs for your domains
  3. Use application-level pinning only for mobile apps and API clients
  4. Always have backup pins for certificate rotation
  5. Set up alerts for new certificate issuance events

Was this article helpful?