Skip to content

Chapter 32: Applied Cryptography for Security Operations

Overview

Cryptography is the mathematical foundation of information security — protecting data confidentiality, ensuring integrity, authenticating identities, and enabling non-repudiation. Security operations professionals must understand not just how to use cryptography, but how it fails: weak algorithms, implementation errors, key management flaws, and quantum threats. This chapter covers symmetric and asymmetric cryptography, PKI, TLS, certificate management, cryptographic failures, and quantum-safe cryptography.

Learning Objectives

By the end of this chapter, students SHALL be able to:

  1. Describe the mathematics and appropriate use cases for symmetric and asymmetric encryption
  2. Implement proper key management and rotation procedures
  3. Analyze TLS/SSL configurations for vulnerabilities and misconfigurations
  4. Design and operate a Public Key Infrastructure (PKI)
  5. Identify cryptographic failures in systems and code
  6. Explain post-quantum cryptography (PQC) and migration planning

Prerequisites

  • Basic mathematics (modular arithmetic helpful but not required)
  • Understanding of SSL/TLS from a network perspective
  • Chapter 30 (Application Security) — cryptographic failures in context

Why This Matters

In 2012, Flame malware used a novel MD5 chosen-prefix collision attack to forge a Microsoft code signing certificate — allowing it to install as a legitimate Windows update. In 2014, Heartbleed exploited a buffer over-read in OpenSSL to extract private keys from running servers. In 2017, ROBOT allowed passive RSA key decryption against HTTPS servers with PKCS#1 v1.5 vulnerabilities unchanged since 1998. Cryptography's failures are always catastrophic because attacks bypass all other security controls. A single cryptographic mistake can undermine years of security investment.


32.1 Symmetric Cryptography

32.1.1 Modern Symmetric Algorithms

Algorithm Key Size Block Size Security Use Case
AES-128 128 bits 128 bits Secure General purpose
AES-256 256 bits 128 bits Very secure High-security, quantum-resistant margin
ChaCha20-Poly1305 256 bits Stream Secure TLS, mobile (no AES-NI hardware)
3DES 112 effective bits 64 bits Deprecated Legacy only — do not use
DES 56 bits 64 bits BROKEN Never use
RC4 Variable Stream BROKEN Never use

32.1.2 Block Cipher Modes

Mode Properties Use
ECB No IV; identical blocks produce identical ciphertext NEVER use
CBC IV required; sequential; padding needed TLS ≤1.2 (deprecated for TLS 1.3)
CTR Stream mode; parallelizable; IV must be unique Acceptable
GCM Authenticated encryption; parallelizable; integrity check Preferred for most use cases
CCM Authenticated encryption; constrained environments IoT
# Python: AES-256-GCM (preferred authenticated encryption)
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
import os

# Key generation (do this ONCE and store securely)
key = AESGCM.generate_key(bit_length=256)  # 32 bytes / 256 bits

aesgcm = AESGCM(key)

# Encrypt
nonce = os.urandom(12)  # 96-bit nonce — MUST be unique per encryption!
plaintext = b"Sensitive data here"
additional_data = b"authenticated but not encrypted header"

ciphertext = aesgcm.encrypt(nonce, plaintext, additional_data)
# ciphertext includes 16-byte GCM authentication tag appended

# Decrypt (throws InvalidTag if ciphertext tampered)
decrypted = aesgcm.decrypt(nonce, ciphertext, additional_data)

# CRITICAL: Never reuse a nonce with the same key!
# GCM nonce reuse breaks confidentiality and integrity completely
# Use random nonce OR counter — never timestamp (not monotonic enough)

32.2 Asymmetric Cryptography

32.2.1 RSA

from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.primitives import hashes

# Key generation
private_key = rsa.generate_private_key(
    public_exponent=65537,  # Always 65537 (F4)
    key_size=4096           # Minimum 2048; prefer 4096 for long-lived keys
)
public_key = private_key.public_key()

# Encryption (for small data, e.g., key wrapping)
ciphertext = public_key.encrypt(
    plaintext,
    padding.OAEP(           # OAEP — always use this, not PKCS1v15
        mgf=padding.MGF1(algorithm=hashes.SHA256()),
        algorithm=hashes.SHA256(),
        label=None
    )
)

# Signing
signature = private_key.sign(
    message,
    padding.PSS(            # PSS — always use this for signing
        mgf=padding.MGF1(hashes.SHA256()),
        salt_length=padding.PSS.MAX_LENGTH
    ),
    hashes.SHA256()
)

RSA Security Notes: - Minimum key size: 2048 bits (NIST deprecated 1024-bit in 2013) - PKCS#1 v1.5 padding → VULNERABLE to Bleichenbacher attack; use OAEP - RSA-1024 can be factored with sufficient compute; RSA-2048 is safe until ~2030 - Post-quantum threat: Shor's algorithm breaks RSA; see Section 32.6

32.2.2 Elliptic Curve Cryptography (ECC)

ECC provides equivalent security with much smaller keys:

ECC Key Size RSA Equivalent Security Level
256 bits (P-256) 3072 bits RSA 128-bit security
384 bits (P-384) 7680 bits RSA 192-bit security
521 bits (P-521) 15360 bits RSA 256-bit security
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey

# Ed25519 — modern, fast, safe (no weak curve parameters)
private_key = Ed25519PrivateKey.generate()
public_key = private_key.public_key()

signature = private_key.sign(message)
public_key.verify(signature, message)  # Raises InvalidSignature if invalid

32.3 Hash Functions

Algorithm Output Security Use
SHA-256 256 bits Secure General hashing, HMAC
SHA-384 384 bits Secure TLS PRF, higher security
SHA-512 512 bits Secure High-security applications
SHA-3 (Keccak) Variable Secure Alternative to SHA-2
SHA-1 160 bits DEPRECATED Legacy only — SHAttered collision 2017
MD5 128 bits BROKEN Never for security; only for checksums

32.3.1 HMAC (Hash-based Message Authentication Code)

import hmac, hashlib

# HMAC — message authentication using shared secret
def sign_message(message: bytes, secret_key: bytes) -> bytes:
    return hmac.new(secret_key, message, hashlib.sha256).digest()

def verify_message(message: bytes, signature: bytes, secret_key: bytes) -> bool:
    expected = sign_message(message, secret_key)
    # MUST use compare_digest — prevents timing attacks
    return hmac.compare_digest(expected, signature)

32.3.2 Password Hashing

import bcrypt
import argon2  # argon2-cffi library

# bcrypt — battle-tested, salt included
hashed = bcrypt.hashpw(password.encode(), bcrypt.gensalt(rounds=12))
# Work factor 12 = ~0.5 seconds per check (appropriate for 2026)

# Argon2id — recommended by OWASP (2024)
ph = argon2.PasswordHasher(
    time_cost=2,         # 2 iterations
    memory_cost=65536,   # 64 MB
    parallelism=1,       # 1 thread
    hash_len=32,
    salt_len=16
)
hash_str = ph.hash(password)
ph.verify(hash_str, password)  # Raises VerifyMismatchError if wrong

32.4 Public Key Infrastructure (PKI)

32.4.1 PKI Architecture

graph TB
    ROOT[Root CA\nOffline / HSM-protected\n20-year cert]
    INTER[Intermediate CA\nOnline signing\n5-year cert]
    LEAF1[TLS Certificate\nweb.example.com\n1-year cert]
    LEAF2[Code Signing Cert\nSoftware Publisher\n2-year cert]
    LEAF3[Client Auth Cert\nEmployee Identity]

    ROOT -->|Signs| INTER
    INTER -->|Signs| LEAF1
    INTER -->|Signs| LEAF2
    INTER -->|Signs| LEAF3

    style ROOT fill:#e63946,color:#fff
    style INTER fill:#1d3557,color:#fff

32.4.2 Certificate Lifecycle Management

# Let's Encrypt / ACME — automated certificate lifecycle
# Certbot — most common ACME client

# Initial certificate issuance
certbot certonly \
  --dns-cloudflare \
  --dns-cloudflare-credentials ~/.secrets/cloudflare.ini \
  -d example.com -d "*.example.com" \
  --preferred-challenges dns-01

# Auto-renewal (runs twice daily via cron)
echo "0 */12 * * * root certbot renew --quiet --deploy-hook 'systemctl reload nginx'" >> /etc/crontab

# Monitor certificate expiry across all domains
# cert-monitor.sh using openssl:
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
  | openssl x509 -noout -dates \
  | grep "notAfter"

# Bulk certificate monitoring (notify 30 days before expiry)
for domain in $(cat domains.txt); do
  expiry=$(echo | openssl s_client -connect $domain:443 -servername $domain 2>/dev/null \
    | openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2)
  days_left=$(( ($(date -d "$expiry" +%s) - $(date +%s)) / 86400 ))
  if [ $days_left -lt 30 ]; then
    echo "EXPIRING SOON: $domain$days_left days ($expiry)"
  fi
done

32.4.3 Certificate Transparency Monitoring

# Monitor CT logs for unauthorized certificates issued for your domain
# crt.sh API
curl -s "https://crt.sh/?q=%.example.com&output=json" | \
  python3 -c "
import sys, json, datetime
for cert in json.load(sys.stdin):
    issuer = cert.get('issuer_name','')
    domain = cert.get('name_value','')
    date = cert.get('entry_timestamp','')[:10]
    print(f'{date} | {domain} | {issuer}')
" | sort -r | head -20

# Automated monitoring: certspotter, facebook CT monitoring, Google CT monitor

32.5 TLS Security

32.5.1 TLS Configuration Hardening

# Nginx TLS 1.3 hardened configuration (2026)
server {
    listen 443 ssl http2;
    server_name example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    # TLS 1.3 only (TLS 1.2 acceptable for compatibility)
    ssl_protocols TLSv1.3 TLSv1.2;

    # Strong cipher suites (TLS 1.3 handles its own; this is for TLS 1.2 compat)
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305;
    ssl_prefer_server_ciphers off;  # Let client choose in TLS 1.3

    # DH parameters for key exchange
    ssl_dhparam /etc/ssl/dhparam.pem;  # openssl dhparam -out dhparam.pem 4096

    # OCSP stapling
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 1.1.1.1 1.0.0.1 valid=300s;

    # Session caching
    ssl_session_cache shared:SSL:50m;
    ssl_session_timeout 1d;
    ssl_session_tickets off;  # Disable for perfect forward secrecy

    # HSTS
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
}

# Generate DH params:
# openssl dhparam -out /etc/ssl/dhparam.pem 4096

32.5.2 TLS Vulnerability Reference

Vulnerability CVE TLS Version Mitigation
BEAST CVE-2011-3389 TLS 1.0 Disable TLS 1.0/1.1
POODLE CVE-2014-3566 SSL 3.0 Disable SSL 3.0
Heartbleed CVE-2014-0160 Any OpenSSL Patch OpenSSL; revoke/reissue certs
FREAK CVE-2015-0204 TLS 1.x Disable export cipher suites
LOGJAM CVE-2015-4000 TLS 1.x Use DH params ≥2048 bits
DROWN CVE-2016-0800 SSLv2 Disable SSLv2 entirely
ROBOT CVE-2017-13099 TLS 1.x Disable RSA key exchange cipher suites
SLOTH CVE-2015-7575 TLS 1.x Disable MD5 and SHA-1 in TLS

32.5.3 SSL Labs Testing

# Automated TLS configuration testing
# sslyze — Python-based TLS scanner
pip3 install sslyze
python3 -m sslyze example.com:443 --json_out results.json

# testssl.sh — comprehensive TLS analysis
./testssl.sh --full https://example.com

# SSL Labs API (grade A+ target)
curl "https://api.ssllabs.com/api/v3/analyze?host=example.com&all=done" | \
  python3 -c "import sys,json; d=json.load(sys.stdin); [print(e['ipAddress'], e['grade']) for e in d.get('endpoints',[])]"

32.6 Post-Quantum Cryptography

32.6.1 The Quantum Threat

Algorithm Classical Security Post-Quantum Status
RSA-2048 112-bit equivalent BROKEN by Shor's algorithm on CRQC
ECDH P-256 128-bit BROKEN by Shor's algorithm on CRQC
AES-128 128-bit Weakened to ~64-bit by Grover's (still okay)
AES-256 256-bit Weakened to ~128-bit by Grover's (secure)
SHA-256 128-bit collision Still secure
SHA-384/512 192/256-bit Secure

CRQC (Cryptographically Relevant Quantum Computer) — A fault-tolerant quantum computer with enough qubits to run Shor's algorithm against RSA-2048. Current estimates: 10-20 years away, but "harvest now, decrypt later" attacks are happening today.

32.6.2 NIST PQC Standards (2024)

NIST finalized the first post-quantum cryptographic standards in 2024:

Standard Algorithm Use Case
FIPS 203 ML-KEM (Kyber) Key encapsulation / key exchange
FIPS 204 ML-DSA (Dilithium) Digital signatures
FIPS 205 SLH-DSA (SPHINCS+) Digital signatures (hash-based, conservative)
FIPS 206 FN-DSA (FALCON) Digital signatures (compact, efficient)

32.6.3 PQC Migration Planning

CRYPTO-AGILITY MIGRATION ROADMAP:

Phase 1 (Now — 2026): Inventory
├── Identify all cryptographic usage across applications, infrastructure
├── Catalog: algorithm, key size, purpose, upgrade difficulty
├── Prioritize: data with long sensitivity lifetime first
└── Establish crypto governance policy

Phase 2 (2026-2028): Hybrid Mode
├── Implement hybrid schemes (classical + PQC in parallel)
├── TLS 1.3 + Kyber key exchange hybrid (already supported in Chrome/Firefox)
├── Begin code library upgrades to PQC-capable versions
└── Test interoperability

Phase 3 (2028-2030): Full Migration
├── Complete migration of high-value, long-lived data
├── PKI migration: issue PQC certificates
├── VPN/TLS: PQC-only or hybrid mode
└── Code signing: migrate to ML-DSA/FN-DSA

Phase 4 (2030+): Deprecation
├── Sunset RSA, ECDSA, ECDH in new deployments
└── Archive and protect long-lived keys until migrated

32.7 Key Management

32.7.1 Key Management Hierarchy

Key Hierarchy:
├── Master Key (KEK — Key Encryption Key)
│   ├── Stored in HSM or cloud KMS
│   ├── Never leaves secure boundary
│   └── Used to encrypt DEKs
├── Data Encryption Keys (DEK)
│   ├── Unique per data set/record
│   ├── Encrypted at rest by KEK
│   └── Rotated regularly
└── Ephemeral Session Keys
    ├── Generated per session
    ├── Never stored
    └── Derived via ECDH / Kyber

32.7.2 HSM and Cloud KMS

# AWS KMS — managed key service
# Create Customer Master Key (CMK)
aws kms create-key --description "Production Database Encryption Key" \
  --key-usage ENCRYPT_DECRYPT \
  --origin AWS_KMS  # Managed by AWS
  # or EXTERNAL for BYOK (Bring Your Own Key)

# Encrypt data with KMS
aws kms encrypt --key-id arn:aws:kms:us-east-1:123456789:key/KEY_ID \
  --plaintext fileb://secret.txt --output text --query CiphertextBlob

# Automatic key rotation (yearly)
aws kms enable-key-rotation --key-id KEY_ID

# Azure Key Vault
az keyvault create --name MyVault --resource-group prod-rg --location eastus
az keyvault key create --vault-name MyVault --name MyKey --kty RSA --size 4096
az keyvault secret set --vault-name MyVault --name DatabasePassword --value "$(cat /dev/urandom | base64 | head -c 32)"

32.8 Benchmark Controls

Control ID Title Requirement
Nexus SecOps-CRY-01 Approved Algorithm Policy No MD5, SHA-1, DES, 3DES, RC4, RSA-1024 in production
Nexus SecOps-CRY-02 TLS Configuration TLS 1.2+ minimum; A grade on SSL Labs; HSTS deployed
Nexus SecOps-CRY-03 Certificate Management Automated renewal; 30-day expiry alerting; CT monitoring
Nexus SecOps-CRY-04 Key Management All encryption keys in KMS or HSM; no keys in code or env vars
Nexus SecOps-CRY-05 Password Hashing bcrypt (rounds≥12) or Argon2id for all password storage
Nexus SecOps-CRY-06 PQC Readiness Crypto inventory complete; migration plan to NIST PQC standards documented

Exam Prep & Certifications

Relevant Certifications

The topics in this chapter align with the following certifications:

  • CISSP — Domains: Security Architecture, Cryptography
  • CCSP — Domains: Cloud Security, Data Protection, Encryption

View full Certifications Roadmap →

Key Terms

Authenticated Encryption (AE/AEAD) — Encryption that simultaneously provides confidentiality and integrity/authenticity guarantees. AES-GCM and ChaCha20-Poly1305 are AEAD algorithms.

Certificate Transparency (CT) — A publicly auditable log of all TLS certificates issued by trusted CAs, enabling detection of mis-issuance.

HSM (Hardware Security Module) — A physical device providing tamper-resistant storage and processing for cryptographic keys and operations.

Perfect Forward Secrecy (PFS) — A property of key exchange protocols where compromise of long-term keys does not compromise past session keys.

Post-Quantum Cryptography (PQC) — Cryptographic algorithms believed to be resistant to attacks from both classical and quantum computers.

PKCS#1 v1.5 — An older RSA padding scheme vulnerable to the Bleichenbacher oracle attack. Always use OAEP for encryption and PSS for signatures.