PKI fundamentals including certificate authorities, chains of trust, X.509 certificates, and certificate lifecycle
Scope: Public Key Infrastructure, certificate authorities, trust chains, X.509 certificates Lines: ~290 Last Updated: 2025-10-27 Format Version: 1.0 (Atomic)
Activate this skill when:
Trust Hierarchy:
Root CA (self-signed, in trust store)
↓
Intermediate CA (signed by Root)
↓
End Entity Certificate (signed by Intermediate)
→ Used by servers, clients, code signing
Certificate Chain:
example.com certificate
├─ Issued by: Intermediate CA
│ └─ Issued by: Root CA
│ └─ Self-signed (trusted)
Structure:
Certificate:
Version: 3
Serial Number: 1234567890abcdef
Signature Algorithm: SHA256-RSA
Issuer: CN=Intermediate CA, O=Trust Corp
Validity:
Not Before: 2025-01-01 00:00:00
Not After: 2026-01-01 00:00:00
Subject: CN=example.com, O=Example Inc
Subject Public Key Info:
Algorithm: RSA 2048-bit
Public Key: (2048-bit modulus)
Extensions:
Subject Alternative Name: example.com, www.example.com
Key Usage: Digital Signature, Key Encipherment
Extended Key Usage: Server Authentication
View Certificate:
# View certificate details
openssl x509 -in cert.pem -text -noout
# Check expiration
openssl x509 -in cert.pem -enddate -noout
# Verify chain
openssl verify -CAfile chain.pem cert.pem
Self-Signed Certificate (for testing):
# Generate private key
openssl genrsa -out private-key.pem 2048
# Create self-signed certificate
openssl req -new -x509 -key private-key.pem -out cert.pem -days 365 \
-subj "/CN=test.example.com/O=Test Org"
Certificate Signing Request (CSR):
# Generate private key
openssl genrsa -out private-key.pem 2048
# Create CSR
openssl req -new -key private-key.pem -out request.csr \
-subj "/CN=example.com/O=Example Inc/C=US"
# Send CSR to CA for signing
# CA returns signed certificate
Certificate Authority Setup:
# Create CA private key
openssl genrsa -out ca-key.pem 4096
# Create CA certificate (self-signed)
openssl req -new -x509 -days 3650 -key ca-key.pem -out ca-cert.pem \
-subj "/CN=My CA/O=Trust Corp"
# Sign a certificate request
openssl x509 -req -in request.csr -CA ca-cert.pem -CAkey ca-key.pem \
-CAcreateserial -out signed-cert.pem -days 365
Python Example:
import ssl
import socket
from datetime import datetime
def validate_certificate(hostname, port=443):
context = ssl.create_default_context()
with socket.create_connection((hostname, port)) as sock:
with context.wrap_socket(sock, server_hostname=hostname) as ssock:
cert = ssock.getpeercert()
# Check subject
subject = dict(x[0] for x in cert['subject'])
print(f"Subject: {subject['commonName']}")
# Check validity
not_after = datetime.strptime(cert['notAfter'], '%b %d %H:%M:%S %Y %Z')
days_remaining = (not_after - datetime.now()).days
print(f"Valid for: {days_remaining} days")
# Check SANs
san = cert.get('subjectAltName', [])
print(f"SANs: {[name for typ, name in san if typ == 'DNS']}")
validate_certificate('example.com')
Go Example:
package main
import (
"crypto/sha256"
"crypto/tls"
"crypto/x509"
"encoding/hex"
"fmt"
"net/http"
)
func verifyPinnedCert(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
// Expected certificate fingerprint (SHA256)
expected := "1234567890abcdef..."
for _, rawCert := range rawCerts {
hash := sha256.Sum256(rawCert)
fingerprint := hex.EncodeToString(hash[:])
if fingerprint == expected {
return nil
}
}
return fmt.Errorf("certificate pinning failed")
}
func main() {
client := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
VerifyPeerCertificate: verifyPinnedCert,
},
},
}
resp, err := client.Get("https://example.com")
if err != nil {
panic(err)
}
defer resp.Body.Close()
}
1. Generate private key
2. Create CSR
3. Submit CSR to CA
4. CA validates domain ownership
5. CA signs certificate
6. Deploy certificate
# Check expiration (90 days before expiry)
if [ $(openssl x509 -enddate -noout -in cert.pem | \
cut -d= -f2 | date -f- +%s) -lt $(date -d "+90 days" +%s) ]; then
echo "Certificate needs renewal"
# Renew via ACME (Let's Encrypt), CA API, or manual process
fi
Certificate Revocation List (CRL):
# Check CRL
openssl crl -in crl.pem -text -noout
OCSP (Online Certificate Status Protocol):
# Check certificate status via OCSP
openssl ocsp -issuer ca-cert.pem -cert cert.pem \
-url http://ocsp.example.com -CAfile ca-cert.pem
# ❌ Bad: Weak 1024-bit RSA
openssl genrsa -out key.pem 1024
# ✅ Good: Strong 2048-bit RSA or better
openssl genrsa -out key.pem 2048
# ✅ Better: ECC (faster, smaller, equally secure)
openssl ecparam -genkey -name prime256v1 -out key.pem
# ❌ Bad: Certificate in code
cert = """-----BEGIN CERTIFICATE-----
MIIBkTCB+wIJAKHHCgK...
-----END CERTIFICATE-----"""
# ✅ Good: Certificate from secure storage
with open('/etc/ssl/certs/cert.pem') as f:
cert = f.read()
// ✅ Good: Verify full chain
roots := x509.NewCertPool()
roots.AppendCertsFromPEM(rootCA)
opts := x509.VerifyOptions{
Roots: roots,
DNSName: "example.com",
}
_, err := cert.Verify(opts)
if err != nil {
log.Fatal("Certificate verification failed:", err)
}
Check expiration:
openssl x509 -in cert.pem -noout -dates
Solution: Renew certificate
Check chain:
openssl s_client -connect example.com:443 -showcerts
Solution: Install intermediate certificates
Symptoms: Certificate CN doesn't match hostname
Solution: Check Subject Alternative Names (SANs)
cryptography-tls-configuration - TLS/SSL setupcryptography-certificate-management - Certificate operationsnetworking-mtls-implementation - Mutual TLScryptography-crypto-best-practices - Security practicesLast Updated: 2025-10-27