PKI, Certificates & Cryptography in Practice
This note covers the applied side of cryptography: how public-key infrastructure works, how TLS/SSL actually secures a connection, how SSH authenticates, and the hardware that underpins system trust.
Public Key Infrastructure (PKI)
Section titled “Public Key Infrastructure (PKI)”PKI is the system of people, processes, and technology that manages public key cryptography at scale. The core problem: how do you trust that a public key really belongs to who they claim?
The Trust Problem: Alice wants to talk to "Bob's Bank". She receives a public key - but how does she know it's really the bank's key and not an attacker's key? She needs a TRUSTED THIRD PARTY to vouch. → That's what a Certificate Authority does.PKI Components
Section titled “PKI Components”| Component | Role |
|---|---|
| Certificate Authority (CA) | Issues, signs, and revokes digital certificates |
| Registration Authority (RA) | Verifies identity of entities requesting certificates |
| Certificate Repository | Secure, indexed storage for issued certificates |
| Certificate Revocation List (CRL) | List of certificates that have been invalidated before expiry |
| OCSP (Online Certificate Status Protocol) | Real-time certificate validity check (alternative to CRL) |
| End-entity / Leaf Certificate | The certificate presented to clients (e.g., your HTTPS cert) |
Chain of Trust
Section titled “Chain of Trust”Root CA (self-signed, offline, stored in OS/browser trust store) └── Intermediate CA (signed by Root CA) └── End-entity certificate (signed by Intermediate CA, presented to user)- Root CAs are self-signed - their trustworthiness is bootstrapped by being pre-installed in your OS or browser (via OS vendors like Apple/Microsoft/Mozilla)
- Intermediate CAs separate the Root (kept offline) from day-to-day signing operations - limits exposure of the root private key
- Leaf certificates are what websites, servers, and clients present
# Inspect full certificate chain of a domainopenssl s_client -connect google.com:443 -showcerts 2>/dev/null | \ openssl x509 -noout -text | grep -A2 "Issuer\|Subject\|Validity"
# Or show the chain visuallyopenssl s_client -connect google.com:443 2>/dev/null | \ sed -n '/-----BEGIN/,/-----END/p' | \ openssl x509 -noout -subject -issuerX.509 Certificates
Section titled “X.509 Certificates”X.509 is the standard format for digital certificates (first published 1988, now on v3). Every HTTPS certificate, code signing certificate, and S/MIME email cert follows this format.
Certificate Fields
Section titled “Certificate Fields”| Field | Contents | Example |
|---|---|---|
| Version | X.509 version (always v3 now) | 3 |
| Serial Number | Unique ID assigned by the CA | 4A:B1:2C:... |
| Signature Algorithm | How the CA signed the cert | sha256WithRSAEncryption |
| Issuer | CA that issued this cert | CN=Let's Encrypt R3, O=Let's Encrypt |
| Validity | Not Before / Not After dates | 2024-01-01 to 2025-01-01 |
| Subject | Who the cert is issued TO | CN=example.com |
| Subject Public Key Info | The public key + algorithm | EC, P-256 |
| Subject Alternative Names (SANs) | Additional hostnames this cert covers | example.com, www.example.com |
| Certificate Signature Value | CA’s digital signature over all fields | (binary) |
# View full certificate detailsopenssl x509 -in certificate.crt -text -noout
# Check just validity datesopenssl x509 -in certificate.crt -noout -dates
# Check Common Name and SANsopenssl x509 -in certificate.crt -noout -subject -ext subjectAltName
# Verify certificate against a CA bundleopenssl verify -CAfile /etc/ssl/certs/ca-certificates.crt certificate.crtCertificate Types
Section titled “Certificate Types”| Type | Purpose | Who Validates |
|---|---|---|
| DV (Domain Validation) | Proves you control the domain | Automated DNS/HTTP challenge |
| OV (Organization Validation) | Proves domain + legal org identity | CA manually verifies org docs |
| EV (Extended Validation) | Strict org identity | Intensive CA vetting |
| Wildcard | Covers *.example.com | DV or OV |
| Client certificate | Authenticates a client to a server | Private CA typically |
| Code signing cert | Signs executables/packages | CA + may require OV |
Certificate Revocation
Section titled “Certificate Revocation”Certificates can be invalidated before they expire (key compromise, org change):
# Check if a cert is revoked via OCSPopenssl ocsp \ -issuer issuer.crt \ -cert site.crt \ -url http://ocsp.example.com \ -resp_textWeb of Trust (alternative to PKI)
Section titled “Web of Trust (alternative to PKI)”PGP and GPG use a decentralised web of trust instead of a central CA hierarchy:
- Individuals sign each other’s public keys after verifying identity in person
- Trust is transitive: if you trust Alice, and Alice signed Bob’s key, you can transitively trust Bob
- No single authority - but also no revocation infrastructure, and trust is hard to bootstrap
# Generate a GPG key pairgpg --full-generate-key
# Export your public key to share
# Sign someone else's key (after verifying their identity)
# Encrypt a file for a recipient
# Sign a filegpg --detach-sign --armor file.txt # produces file.txt.ascTLS / HTTPS - How Secure Connections Work
Section titled “TLS / HTTPS - How Secure Connections Work”TLS (Transport Layer Security) is what makes HTTPS work. It provides:
- Confidentiality - data is encrypted
- Integrity - data cannot be modified without detection
- Authentication - server proves its identity via certificate
TLS 1.3 Handshake (simplified)
Section titled “TLS 1.3 Handshake (simplified)”Client Server │── ClientHello ──────────────────→│ │ (supported cipher suites, │ │ key share, TLS version) │ │ │ │←── ServerHello + Certificate ───│ │ (chosen cipher, server's │ │ public key share, │ │ certificate) │ │ │ │── [verify cert against CA] ── │ │── [derive session keys via ECDH]─│ │ │ │── Finished (encrypted) ─────────→│ │←── Finished (encrypted) ────────│ │ │ │══ Encrypted application data ═══│Key improvements in TLS 1.3 vs 1.2:
- 1-RTT handshake (vs 2-RTT) = faster connection setup
- 0-RTT resumption for returning connections (with replay attack caveats)
- Forward secrecy is mandatory (ECDHE only - no static RSA key exchange)
- Eliminated weak cipher suites (RC4, 3DES, MD5, SHA-1)
Forward Secrecy
Section titled “Forward Secrecy”Even if the server’s private key is stolen years later, past sessions remain private because session keys are ephemeral (ECDHE - generated fresh for each session, then discarded).
# Test what TLS versions and ciphers a server supportsopenssl s_client -connect example.com:443 -tls1_3
# Full TLS inspection with nmapnmap --script ssl-enum-ciphers -p 443 example.com
# Check if a server supports TLS 1.0/1.1 (should not)openssl s_client -connect example.com:443 -tls1SSH - Secure Shell
Section titled “SSH - Secure Shell”SSH provides encrypted remote access to command-line systems. It uses the same public-key cryptography principles as TLS but in a different protocol.
Authentication Methods (in order of security)
Section titled “Authentication Methods (in order of security)”| Method | How it works | When to use |
|---|---|---|
| Key-based | Client holds private key; server has public key in ~/.ssh/authorized_keys | Always prefer this |
| Certificate-based | SSH CA signs user/host keys; eliminates managing individual authorized_keys | Large scale deployments |
| Password | Username + password over encrypted channel | Disable in production |
| None | No authentication | Never |
Key Generation
Section titled “Key Generation”# Generate Ed25519 key pair (preferred - fast, secure, small)
# Generate RSA key (for compatibility with older systems)
# Copy public key to a remote serverssh-copy-id -i ~/.ssh/id_ed25519.pub user@host
# Manually add public key to authorised_keyscat ~/.ssh/id_ed25519.pub >> ~/.ssh/authorized_keyschmod 600 ~/.ssh/authorized_keysHardening sshd_config
Section titled “Hardening sshd_config”# /etc/ssh/sshd_config - key settings
Port 2222 # Non-default port (minor obscurity)PermitRootLogin no # Never allow root loginPasswordAuthentication no # Key-only authPubkeyAuthentication yesAuthorizedKeysFile .ssh/authorized_keysMaxAuthTries 3LoginGraceTime 20AllowUsers alice bob # Allowlist specific usersClientAliveInterval 300 # Disconnect idle sessions after 5mClientAliveCountMax 2
# Restart after changessudo systemctl restart sshd# Verify no password auth is possiblessh -o PasswordAuthentication=yes user@host# should fail: "Permission denied (publickey)"Cryptographic Hardware
Section titled “Cryptographic Hardware”Trusted Platform Module (TPM)
Section titled “Trusted Platform Module (TPM)”A dedicated secure chip soldered to the motherboard. Provides:
| Function | What it does |
|---|---|
| Secure key generation | Generates truly random keys inside tamper-resistant hardware |
| Hardware attestation | Proves to remote systems that the hardware+software configuration is unmodified |
| Data binding | Encrypts data to this specific TPM - migrating to another device fails to decrypt |
| Data sealing | Encrypts data AND locks it to a specific system state (e.g., only decrypts if Secure Boot passed) |
| Full Disk Encryption | BitLocker (Windows), systemd-cryptenroll (Linux) use TPM to auto-unlock FDE |
# Check if TPM 2.0 is present and active (Linux)ls /dev/tpm* # device nodestpm2-tools tpm2_getcap properties-fixed
# Enrol TPM for LUKS disk encryption (systemd)systemd-cryptenroll --tpm2-device=auto /dev/sda3Full Disk Encryption (FDE) Architecture
Section titled “Full Disk Encryption (FDE) Architecture”Disk layout with FDE:
┌─────────────────────────────────────────────────────────────┐│ /boot (UNENCRYPTED) ││ kernel, bootloader, initramfs │├─────────────────────────────────────────────────────────────┤│ / root volume (ENCRYPTED - AES-256-XTS) ││ OS, user data, everything else ││ Unlocks at boot via: ││ - TPM (auto, if PCR values match) ││ - Passphrase (manual entry) ││ - Recovery key (stored offline) │└─────────────────────────────────────────────────────────────┘FDE tools:
| Platform | Tool | Underlying Crypto |
|---|---|---|
| Linux | dm-crypt / LUKS | AES-256-XTS |
| macOS | FileVault 2 | AES-128-XTS |
| Windows | BitLocker | AES-128 or AES-256-XTS |
| Cross-platform | VeraCrypt | AES, Serpent, Twofish |
# Set up LUKS encryption on a partition (Linux)cryptsetup luksFormat /dev/sdb1 # initialise LUKScryptsetup open /dev/sdb1 secure_data # unlock to /dev/mapper/secure_datamkfs.ext4 /dev/mapper/secure_data # create filesystemmount /dev/mapper/secure_data /mnt/secure # mount
# Add a second passphrase (recovery key) to LUKScryptsetup luksAddKey /dev/sdb1Random Number Generation
Section titled “Random Number Generation”Cryptography lives or dies by randomness. Predictable “random” numbers → predictable keys → broken encryption.
| Source | Description | Use case |
|---|---|---|
/dev/urandom | Non-blocking CSPRNG (Linux) | General crypto; safe to use after boot |
/dev/random | Blocks until entropy pool refilled (older kernel) | Legacy - no advantage over urandom on Linux 5.6+ |
| RDRAND (CPU) | Intel/AMD hardware RNG instruction | Feeds entropy pool; fast |
| TPM RNG | Hardware RNG from TPM chip | High-assurance keys |
# Generate 32 bytes of cryptographically secure random datadd if=/dev/urandom bs=32 count=1 | base64
# Or using opensslopenssl rand -base64 32
# Check entropy pool size (Linux)cat /proc/sys/kernel/random/entropy_availCreating a Local CA (Self-Signed PKI)
Section titled “Creating a Local CA (Self-Signed PKI)”Useful for internal services, dev environments, or lab setups.
# 1. Create root CA key and self-signed certificateopenssl genrsa -out rootCA.key 4096openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 1826 \ -out rootCA.crt \ -subj "/C=US/O=MyOrg CA/CN=MyOrg Root CA"
# 2. Generate server key and CSR (Certificate Signing Request)openssl genrsa -out server.key 2048openssl req -new -key server.key -out server.csr \ -subj "/C=US/O=MyOrg/CN=internal.myorg.com"
# 3. Sign the server certificate with the root CAopenssl x509 -req -in server.csr -CA rootCA.crt -CAkey rootCA.key \ -CAcreateserial -out server.crt -days 365 -sha256 \ -extfile <(printf "subjectAltName=DNS:internal.myorg.com,DNS:localhost")
# 4. Verify the chainopenssl verify -CAfile rootCA.crt server.crt
# 5. Trust the root CA system-wide (Ubuntu/Debian)sudo cp rootCA.crt /usr/local/share/ca-certificates/sudo update-ca-certificates