Luke a Pro

Luke Sun

Developer & Marketer

๐Ÿ‡บ๐Ÿ‡ฆ

Certificates and PKI: Building Trust on the Internet

| , 12 minutes reading.

1. Why Should You Care?

You visit https://bank.example.com. Your browser shows a padlock. How does it know this is really your bank and not an attacker?

The answer is certificatesโ€”digital documents that bind public keys to identities. Without them, HTTPS would be meaningless.

Understanding PKI helps you:

  • Debug TLS certificate errors
  • Set up HTTPS for your applications
  • Understand why โ€œjust click through the warningโ€ is dangerous
  • Know when and how to use client certificates

2. Definition

A digital certificate (specifically X.509) binds:

  • A public key
  • An identity (domain name, organization, etc.)
  • A signature from a trusted authority

Public Key Infrastructure (PKI) is the system of:

  • Certificate Authorities (CAs) that issue certificates
  • Policies for issuing and revoking certificates
  • Trust stores containing trusted root certificates
Certificate = "I, Trusted CA, certify that
               public key XYZ belongs to bank.example.com"
               + CA's signature

3. Whatโ€™s Inside a Certificate

X.509 Certificate Structure

Certificate:
    Version: 3
    Serial Number: 04:00:00:00:00:01:2F:4E:E1:5B:3D
    Signature Algorithm: sha256WithRSAEncryption
    Issuer: CN=DigiCert Global Root CA
    Validity:
        Not Before: Mar 08 12:00:00 2023 GMT
        Not After:  Mar 08 12:00:00 2024 GMT
    Subject: CN=www.example.com
    Subject Public Key Info:
        Public Key Algorithm: id-ecPublicKey
        EC Public Key:
            pub: 04:AB:CD:...
            ASN1 OID: prime256v1
    X509v3 Extensions:
        Subject Alternative Name:
            DNS:www.example.com
            DNS:example.com
        Basic Constraints:
            CA:FALSE
        Key Usage:
            Digital Signature, Key Encipherment
        Extended Key Usage:
            TLS Web Server Authentication

Key Fields Explained

Subject: Who the certificate is for
  CN=www.example.com (Common Name)
  O=Example Inc (Organization)

Issuer: Who signed the certificate
  The CA that vouches for this identity

Validity: When the certificate is valid
  Not Before / Not After dates

Subject Alternative Name (SAN):
  Additional domains covered
  Modern browsers require this

Key Usage:
  What the key can be used for
  Digital Signature, Key Encipherment, etc.

Extended Key Usage:
  More specific purposes
  TLS Web Server Authentication
  Code Signing, etc.

4. The Chain of Trust

How Trust Works

Root CA (Self-signed, in browser trust store)
    โ”‚
    โ”‚ signs
    โ–ผ
Intermediate CA Certificate
    โ”‚
    โ”‚ signs
    โ–ผ
End-Entity Certificate (your website)

Browser verifies:
1. End certificate signed by intermediate
2. Intermediate signed by root
3. Root is in trusted store
4. All certificates are valid (not expired, not revoked)

Why Intermediates?

Security: Root keys are extremely valuable
  - Stored in offline HSMs
  - Used rarely (to sign intermediates)
  - If compromised, entire PKI collapses

Flexibility:
  - Intermediates can be revoked if compromised
  - Different intermediates for different purposes
  - Shorter validity periods

Defense in depth:
  - One more layer to compromise
  - Can rotate intermediates without changing roots

5. Certificate Authorities (CAs)

What CAs Do

1. Verify identity of certificate requestor
   - Domain Validation (DV): Prove you control domain
   - Organization Validation (OV): Verify organization exists
   - Extended Validation (EV): Extensive legal verification

2. Issue certificates
   - Sign with CA's private key
   - Include appropriate constraints

3. Maintain revocation information
   - CRL (Certificate Revocation List)
   - OCSP (Online Certificate Status Protocol)

4. Protect their keys
   - Root keys in HSMs
   - Strict access controls
   - Regular audits

Major CAs

Commercial:
- DigiCert
- Sectigo (formerly Comodo)
- GlobalSign
- Entrust

Free:
- Let's Encrypt (automated DV certificates)
- ZeroSSL

Private:
- Your organization's internal CA
- For internal services, client certificates

6. Getting a Certificate

Using Letโ€™s Encrypt (Free, Automated)

# Install certbot
sudo apt install certbot

# Get certificate (standalone mode)
sudo certbot certonly --standalone -d example.com -d www.example.com

# Certificate files:
# /etc/letsencrypt/live/example.com/fullchain.pem  (cert + intermediates)
# /etc/letsencrypt/live/example.com/privkey.pem   (private key)

# Auto-renewal (runs twice daily)
sudo certbot renew

Using ACME Protocol (Programmatic)

# Conceptual example using acme library
from acme import client, messages
from cryptography.hazmat.primitives.asymmetric import ec

# Generate account key
account_key = ec.generate_private_key(ec.SECP256R1())

# Create ACME client
acme_client = client.ClientV2(
    directory='https://acme-v02.api.letsencrypt.org/directory',
    key=account_key
)

# Request certificate for domain
order = acme_client.new_order(['example.com'])

# Complete challenges (prove domain ownership)
for auth in order.authorizations:
    challenge = get_http_challenge(auth)
    # Deploy challenge response
    # ...
    acme_client.answer_challenge(challenge)

# Finalize and get certificate
certificate = acme_client.finalize_order(order, csr)

7. Certificate Validation

What Browsers Check

1. Signature chain is valid
   โ””โ”€ Each certificate signed by its issuer

2. Root CA is trusted
   โ””โ”€ In browser/OS trust store

3. Certificate is not expired
   โ””โ”€ Current time within validity period

4. Certificate is not revoked
   โ””โ”€ Check CRL or OCSP

5. Domain matches
   โ””โ”€ Subject or SAN contains the domain

6. Key usage is appropriate
   โ””โ”€ TLS Web Server Authentication

7. Certificate policies are met
   โ””โ”€ Various X.509 constraints

Validation Code Example

from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.x509.oid import ExtensionOID
import ssl
import socket
import datetime

def validate_server_certificate(hostname, port=443):
    """Validate a server's certificate"""
    # Get certificate
    context = ssl.create_default_context()
    with socket.create_connection((hostname, port)) as sock:
        with context.wrap_socket(sock, server_hostname=hostname) as ssock:
            der_cert = ssock.getpeercert(binary_form=True)

    cert = x509.load_der_x509_certificate(der_cert, default_backend())

    # Check validity period
    now = datetime.datetime.utcnow()
    if now < cert.not_valid_before or now > cert.not_valid_after:
        return False, "Certificate expired or not yet valid"

    # Check subject alternative names
    try:
        san = cert.extensions.get_extension_for_oid(
            ExtensionOID.SUBJECT_ALTERNATIVE_NAME
        )
        names = san.value.get_values_for_type(x509.DNSName)
        if hostname not in names:
            return False, f"Hostname {hostname} not in SAN"
    except x509.ExtensionNotFound:
        return False, "No SAN extension"

    return True, "Certificate valid"

# Check
valid, message = validate_server_certificate("www.google.com")
print(f"Valid: {valid}, Message: {message}")

8. Certificate Revocation

Why Revocation Matters

Scenarios requiring revocation:
- Private key compromised
- Certificate issued incorrectly
- Domain ownership changed
- Organization no longer trusted

Without revocation checking:
- Attacker with stolen key can impersonate site
- Until certificate naturally expires (up to 398 days!)

CRL vs OCSP

CRL (Certificate Revocation List):
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Big list of revoked serials    โ”‚
โ”‚ Downloaded periodically        โ”‚
โ”‚ Can be megabytes               โ”‚
โ”‚ Delay between updates          โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

OCSP (Online Certificate Status Protocol):
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Query: "Is this cert revoked?" โ”‚
โ”‚ Response: "Yes/No"             โ”‚
โ”‚ Real-time                      โ”‚
โ”‚ Privacy concerns (CA sees)     โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

OCSP Stapling:
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Server fetches OCSP response   โ”‚
โ”‚ Staples to TLS handshake       โ”‚
โ”‚ Client gets fresh proof        โ”‚
โ”‚ No privacy leak to CA          โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

9. Common Certificate Problems

Certificate Errors and Solutions

Error: NET::ERR_CERT_DATE_INVALID
Cause: Certificate expired or not yet valid
Fix: Renew certificate, check server clock

Error: NET::ERR_CERT_AUTHORITY_INVALID
Cause: CA not trusted
Fix: Use well-known CA, or install root cert

Error: NET::ERR_CERT_COMMON_NAME_INVALID
Cause: Domain not in certificate
Fix: Get certificate with correct SAN

Error: SSL_ERROR_BAD_CERT_DOMAIN
Cause: Hostname mismatch
Fix: Access using correct hostname

Error: Certificate chain incomplete
Cause: Missing intermediate certificates
Fix: Configure server with full chain

Debugging Certificates

# View certificate details
openssl s_client -connect example.com:443 -showcerts

# Check certificate dates
openssl s_client -connect example.com:443 2>/dev/null | \
  openssl x509 -noout -dates

# Check certificate chain
openssl s_client -connect example.com:443 -showcerts 2>/dev/null | \
  openssl x509 -noout -issuer -subject

# Verify certificate
openssl verify -CAfile ca-bundle.crt certificate.pem

10. Client Certificates

What Theyโ€™re For

Server certificates: Server proves identity to client
Client certificates: Client proves identity to server

Use cases:
- Mutual TLS (mTLS) for service-to-service auth
- User authentication without passwords
- IoT device authentication
- VPN authentication

Setting Up mTLS

import ssl
import socket

# Server side
server_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
server_context.load_cert_chain('server.crt', 'server.key')
server_context.load_verify_locations('client-ca.crt')
server_context.verify_mode = ssl.CERT_REQUIRED  # Require client cert

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
    sock.bind(('0.0.0.0', 8443))
    sock.listen()
    with server_context.wrap_socket(sock, server_side=True) as ssock:
        conn, addr = ssock.accept()
        # conn.getpeercert() returns client certificate

# Client side
client_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
client_context.load_cert_chain('client.crt', 'client.key')
client_context.load_verify_locations('server-ca.crt')

with socket.create_connection(('server.example.com', 8443)) as sock:
    with client_context.wrap_socket(sock, server_hostname='server.example.com') as ssock:
        # Connected with mutual authentication
        pass

11. Self-Signed Certificates

When to Use

Appropriate:
- Development and testing
- Internal services (with private CA)
- Learning and experimentation

Not appropriate:
- Public-facing websites
- Production APIs used by external clients
- Anywhere trust matters

Creating a Self-Signed Certificate

# Generate private key
openssl genrsa -out server.key 2048

# Generate self-signed certificate
openssl req -new -x509 -key server.key -out server.crt -days 365 \
  -subj "/CN=localhost"

# With SAN extension (required by modern browsers)
openssl req -new -x509 -key server.key -out server.crt -days 365 \
  -subj "/CN=localhost" \
  -addext "subjectAltName=DNS:localhost,IP:127.0.0.1"

12. Certificate Transparency

The Problem It Solves

What if a CA issues a certificate for your domain?
- You might never know
- Attacker could intercept traffic
- CA compromise is catastrophic

Certificate Transparency:
- All certificates logged to public logs
- You can monitor logs for your domains
- Misissued certificates are detectable

How It Works

1. CA issues certificate
2. CA submits to CT logs
3. Log returns Signed Certificate Timestamp (SCT)
4. Certificate includes SCT
5. Browsers verify SCT present
6. Domain owners monitor logs

Tools:
- crt.sh (search CT logs)
- Google Certificate Transparency
- Cert Spotter (monitoring)

13. Summary

Three things to remember:

  1. Certificates bind keys to identities. A certificate is a signed statement from a CA that a public key belongs to a specific domain or entity.

  2. Trust flows from root CAs. Your browser trusts ~100 root CAs. Those CAs sign intermediates, which sign end certificates. If any link is broken, trust fails.

  3. Certificate management is operational. Renewals, revocations, and chain configuration are ongoing work. Automate with Letโ€™s Encrypt where possible.

14. Whatโ€™s Next

Weโ€™ve covered asymmetric cryptography, signatures, and certificates. But thereโ€™s another fundamental primitive: ensuring data hasnโ€™t been modified without proving who modified it.

In the next article: HMAC and Data Integrityโ€”how to detect tampering with symmetric keys, when you already share a secret.