From f5e0d8de0a54f68cdf89a0489ae55c565c1182f5 Mon Sep 17 00:00:00 2001 From: Samuel Laferriere <9342524+samlaf@users.noreply.github.com> Date: Sun, 21 Jun 2026 19:43:30 +0800 Subject: [PATCH 1/5] rename duality -> --- _drafts/crypto-series/2026-06-04-crypto-series-intro.md | 4 ++-- _drafts/crypto-series/2026-06-07-secure-channels.md | 2 +- _drafts/crypto-series/2026-06-08-authentication.md | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/_drafts/crypto-series/2026-06-04-crypto-series-intro.md b/_drafts/crypto-series/2026-06-04-crypto-series-intro.md index 3309fa7..1b803b5 100644 --- a/_drafts/crypto-series/2026-06-04-crypto-series-intro.md +++ b/_drafts/crypto-series/2026-06-04-crypto-series-intro.md @@ -6,14 +6,14 @@ date: 2026-06-04 This is the intro to a short series on applied cryptography — not the math, but the engineering: which primitives exist, how they compose into channels and authentication, and where all the trust ultimately bottoms out. -## The duality that runs through everything +## The split that runs through everything Every byte that moves over a network forces two independent questions: 1. **Who is this from?** — *identity / authentication.* Certs, passkeys, signatures, tokens. 2. **Who else can see or change it?** — *data protection.* Confidentiality + integrity: TLS records, AEAD, envelope encryption, end-to-end encryption. -They're **orthogonal**. You can have one without the other: raw Diffie–Hellman gives you a confidential channel with no idea who's on the other end; a bare signature proves origin while hiding nothing. Real systems answer both, at several layers that stack on top of each other — and almost every topic in this series is one half of that duality, pointed at one layer. +They're **orthogonal**. You can have one without the other: raw Diffie–Hellman gives you a confidential channel with no idea who's on the other end; a bare signature proves origin while hiding nothing. Real systems answer both, at several layers that stack on top of each other — and almost every topic in this series is one half of that split, pointed at one layer. Here's the way to *feel* the split: **once two parties share a secret, an AEAD turns it into a secure channel almost for free.** So nearly all the real difficulty reduces to the two sub-problems of getting that shared secret in the first place — **(a) establishing it safely**, and **(b) knowing it's shared with the *right* party.** (a) is the data-protection arm (key exchange, plus the key material itself); (b) is the identity arm (authentication, plus the roots of trust that make any identity believable). diff --git a/_drafts/crypto-series/2026-06-07-secure-channels.md b/_drafts/crypto-series/2026-06-07-secure-channels.md index 846cc69..aa2470d 100644 --- a/_drafts/crypto-series/2026-06-07-secure-channels.md +++ b/_drafts/crypto-series/2026-06-07-secure-channels.md @@ -6,7 +6,7 @@ category: programming date: 2026-06-07 --- -This is the data-protection arm of the [identity / data-protection duality](/programming/crypto-series-intro.html): how two parties agree on a shared key and protect bytes in transit. (The identity arm — proving *who* the other party is — gets its own [Authentication](/programming/authentication.html) post; the two are usually fused in practice but conceptually separate.) +This is the data-protection arm of the [identity / data-protection split](/programming/crypto-series-intro.html): how two parties agree on a shared key and protect bytes in transit. (The identity arm — proving *who* the other party is — gets its own [Authentication](/programming/authentication.html) post; the two are usually fused in practice but conceptually separate.) The whole post rests on one observation: **once two parties share a secret, an AEAD turns it into a secure channel almost trivially.** So the entire difficulty is *safely establishing that shared secret* — which is what everything below is about. (The other half of the problem, knowing the secret is shared with the *right* party, is [Authentication](/programming/authentication.html) and [Roots of Trust & Attestation](/programming/roots-of-trust-and-attestation.html).) diff --git a/_drafts/crypto-series/2026-06-08-authentication.md b/_drafts/crypto-series/2026-06-08-authentication.md index ec33abf..48764b1 100644 --- a/_drafts/crypto-series/2026-06-08-authentication.md +++ b/_drafts/crypto-series/2026-06-08-authentication.md @@ -6,7 +6,7 @@ category: programming date: 2026-06-08 --- -This is the identity arm of the [duality](/programming/crypto-series-intro.html): proving *who* a party is, as opposed to protecting *what* they send (that's [Key Exchange & Secure Channels](/programming/secure-channels.html)). The two are usually fused in a handshake, but they're separable — and authentication has its own 50-year story worth telling on its own. +This is the identity arm of the [split](/programming/crypto-series-intro.html): proving *who* a party is, as opposed to protecting *what* they send (that's [Key Exchange & Secure Channels](/programming/secure-channels.html)). The two are usually fused in a handshake, but they're separable — and authentication has its own 50-year story worth telling on its own. ## The actors From a258dfe526aed44cc3c98cc1ef46fd4b1df99cbb Mon Sep 17 00:00:00 2001 From: Samuel Laferriere <9342524+samlaf@users.noreply.github.com> Date: Sun, 21 Jun 2026 19:49:44 +0800 Subject: [PATCH 2/5] add paragraph about non-repudiation --- _drafts/crypto-series/2026-06-06-crypto-primitives.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/_drafts/crypto-series/2026-06-06-crypto-primitives.md b/_drafts/crypto-series/2026-06-06-crypto-primitives.md index 6c267bf..d05c9b9 100644 --- a/_drafts/crypto-series/2026-06-06-crypto-primitives.md +++ b/_drafts/crypto-series/2026-06-06-crypto-primitives.md @@ -76,6 +76,8 @@ In the formal vocabulary: bare confidentiality only buys you IND-CPA (security a **Signatures (asymmetric authentication).** A MAC's limitation is that verifying requires the same secret used to sign — so the verifier can also forge. Signatures break that symmetry: a private key signs, and a *public* key verifies, so anyone can check authenticity without being able to forge. That asymmetry is what makes signatures the backbone of identity at a distance — certificates, software signing, the passkey login in the [Authentication](/programming/authentication.html) post, the quote-signing keys in the [Attestation](/programming/roots-of-trust-and-attestation.html) post. RSA, ECDSA (NIST curves), and EdDSA (Ed25519) are the workhorses; the deterministic-nonce trick in EdDSA / RFC 6979 is, again, just a PRF over `(private_key, message)` — the same "PRF in counter mode" idea from the diagram above, reused to avoid catastrophic nonce reuse. +That same asymmetry decides a property protocols care about on its own: **non-repudiation**. Only the private-key holder could have produced a signature, so a *third party* can be convinced who signed — the signer can't later deny it. A MAC gives the mirror image: since either party could have forged the tag, neither can prove to anyone else who made it. Usually that's a limitation — but sometimes it's the point, and Signal and OTR authenticate with symmetric MACs precisely so messages stay **deniable**. + The throughline: a MAC is the integrity twin of symmetric encryption, and a signature is the integrity twin of asymmetric encryption. Confidentiality hides content; authentication binds it to a holder of a key. Real protocols always want both — which is why AEAD fuses them, and why the channel and authentication posts lean on these primitives constantly. ## References From 0843f54425c1a1a7d83764aecaca7f5398d549e1 Mon Sep 17 00:00:00 2001 From: Samuel Laferriere <9342524+samlaf@users.noreply.github.com> Date: Sun, 21 Jun 2026 20:15:36 +0800 Subject: [PATCH 3/5] add availability to capstone --- .../crypto-series/2026-06-10-roots-of-trust-and-attestation.md | 1 + 1 file changed, 1 insertion(+) diff --git a/_drafts/crypto-series/2026-06-10-roots-of-trust-and-attestation.md b/_drafts/crypto-series/2026-06-10-roots-of-trust-and-attestation.md index f9e3c8c..0497420 100644 --- a/_drafts/crypto-series/2026-06-10-roots-of-trust-and-attestation.md +++ b/_drafts/crypto-series/2026-06-10-roots-of-trust-and-attestation.md @@ -106,6 +106,7 @@ We've now walked the whole stack — primitives, channels, keys, authentication, - Unauthorized. Authentication answers "who"; it doesn't answer "may they". You will write the authz layer. Every time. Capabilities (macaroons, biscuits), ACLs, role tables, OPA — all of it lives above the channel. - Nameless. Public keys aren't names. You will build, or import, a naming layer (Zooko's triangle applies: secure / human-meaningful / decentralized — pick two). Petnames, ENS, DNS-over-something, .onion vanity, GPG WoT. All ad hoc, none portable. - Stale. Keys leak, certs expire, devices get lost, employees quit. You need rotation, revocation, and a story for "this was Alice and now isn't." CRL/OCSP, short-lived certs (SPIFFE), key transparency, ratchets. The state machine for "current trust" is its own distributed system. +- Killable. The channel says nothing about staying *up* — and crypto only ever *subtracts* from availability. An unauthenticated handshake packet makes you do expensive asymmetric work for free (client puzzles, SYN/DTLS cookies, WireGuard's cookie reply all exist to claw that back); a lost or revoked key is permanent denial-of-access; ransomware is just confidentiality pointed at you. Availability is the third leg of the CIA triad, and the channel is the wrong layer to ask for it — it lives in redundancy, rate limits, and capacity, not crypto. - Brittle (cryptographically). Algorithms get deprecated faster than your dependency tree updates. SHA-1, RC4, MD5, soon RSA-2048 and ECDH against a quantum adversary. Cipher agility is the "Mismatched" problem on hard mode — you can't just add a JSON field, you have to renegotiate primitives without opening a downgrade attack. (See the negotiation-as-footgun discussion in [Key Exchange & Secure Channels](/programming/secure-channels.html) — agility is exactly the attack surface TLS keeps getting burned by.) - Leaky. The channel encrypts content but not envelope: who talks to whom, when, how often, how much. Traffic analysis, timing, sizes, fingerprintable handshakes (JA3/JA4). Padding, cover traffic, mixnets — and each of those is its own pile of work. - Replayable. A single channel handles ordering inside its lifetime, but the moment your message escapes the channel (queued, logged, persisted, cross-session) freshness becomes your problem again. Nonces, timestamps, sequence numbers, idempotency keys — all rebuilt at the app layer. From bf5a35a4b134a6b745b1ece096f2e923a02e845e Mon Sep 17 00:00:00 2001 From: Samuel Laferriere <9342524+samlaf@users.noreply.github.com> Date: Sun, 21 Jun 2026 20:29:44 +0800 Subject: [PATCH 4/5] add cia diagram to intro --- .../2026-06-04-crypto-series-intro.md | 8 ++- assets/crypto-series-intro/two-splits.svg | 56 +++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 assets/crypto-series-intro/two-splits.svg diff --git a/_drafts/crypto-series/2026-06-04-crypto-series-intro.md b/_drafts/crypto-series/2026-06-04-crypto-series-intro.md index 1b803b5..6fbcfb3 100644 --- a/_drafts/crypto-series/2026-06-04-crypto-series-intro.md +++ b/_drafts/crypto-series/2026-06-04-crypto-series-intro.md @@ -11,10 +11,16 @@ This is the intro to a short series on applied cryptography — not the math, bu Every byte that moves over a network forces two independent questions: 1. **Who is this from?** — *identity / authentication.* Certs, passkeys, signatures, tokens. -2. **Who else can see or change it?** — *data protection.* Confidentiality + integrity: TLS records, AEAD, envelope encryption, end-to-end encryption. +2. **Who else can see or change it?** — *data protection.* Confidentiality + *data* integrity: TLS records, AEAD, envelope encryption, end-to-end encryption. They're **orthogonal**. You can have one without the other: raw Diffie–Hellman gives you a confidential channel with no idea who's on the other end; a bare signature proves origin while hiding nothing. Real systems answer both, at several layers that stack on top of each other — and almost every topic in this series is one half of that split, pointed at one layer. +In CIA-triad terms, the data-protection arm is *confidentiality + integrity*, and the identity arm is integrity aimed at origin — *authenticity*. The third leg, **availability**, is deliberately not in this series: it isn't a property cryptography provides. If anything, crypto *subtracts* from it — ransomware is confidentiality turned against you, an expensive handshake is a denial-of-service vector, a lost key is permanent unavailability. And the properties people bolt onto the triad — non-repudiation, deniability, authenticity — aren't a fourth pillar either; they're refinements of integrity (precisely the [MAC-vs-signature](/programming/crypto-primitives.html) split), so everything here really does reduce to those two arms. + +![Two ways to partition the same three guarantees — confidentiality, data integrity, and authentication (origin integrity). The C/I "property" split groups data and origin integrity together as integrity, cutting after confidentiality. This series' "difficulty" split instead groups confidentiality with data integrity as data protection, cutting after data integrity and leaving authentication as identity. Data integrity is the swing cell — it lands on a different side depending on which split you use.](/assets/crypto-series-intro/two-splits.svg) + +Same three atoms, cut two ways: the C / I split divides by *property*, this series by *engineering difficulty* — with data integrity the swing that lands on either side depending on which cut you take. + Here's the way to *feel* the split: **once two parties share a secret, an AEAD turns it into a secure channel almost for free.** So nearly all the real difficulty reduces to the two sub-problems of getting that shared secret in the first place — **(a) establishing it safely**, and **(b) knowing it's shared with the *right* party.** (a) is the data-protection arm (key exchange, plus the key material itself); (b) is the identity arm (authentication, plus the roots of trust that make any identity believable). (There's a subtlety the series keeps returning to: key establishment and authentication are *usually* fused but are conceptually separable — Diffie–Hellman is the notable exception that establishes a shared key while authenticating nobody.) diff --git a/assets/crypto-series-intro/two-splits.svg b/assets/crypto-series-intro/two-splits.svg new file mode 100644 index 0000000..830f643 --- /dev/null +++ b/assets/crypto-series-intro/two-splits.svg @@ -0,0 +1,56 @@ + + + + +Two ways to cut the same three guarantees +The same three atoms, partitioned by property (C / I) and by engineering difficulty (what this series does). + + +By property — the C / I split · primitives view + + +Confidentiality + + +Integrity +data + origin + + + + +Confidentiality +who can read it + + + +the swing +Data integrity +unchanged in transit + + +Authentication +origin integrity — who it's from + + +By engineering difficulty — what this series does + + +Data protection +confidentiality + data integrity — fuse into an AEAD + + +Identity +authenticate the peer + + + + + + + + + +Data integrity is the swing — “integrity” by property, part of “data protection” by difficulty. +Once a key is shared, confidentiality + data integrity fuse into an AEAD; the hard, separable problem is the last column. + + From f116df3623eec92dccc6020134c137f368fffbf3 Mon Sep 17 00:00:00 2001 From: Samuel Laferriere <9342524+samlaf@users.noreply.github.com> Date: Sun, 21 Jun 2026 20:37:26 +0800 Subject: [PATCH 5/5] add server auth --- .../2026-06-08-authentication.md | 59 ++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/_drafts/crypto-series/2026-06-08-authentication.md b/_drafts/crypto-series/2026-06-08-authentication.md index 48764b1..9866456 100644 --- a/_drafts/crypto-series/2026-06-08-authentication.md +++ b/_drafts/crypto-series/2026-06-08-authentication.md @@ -8,6 +8,8 @@ date: 2026-06-08 This is the identity arm of the [split](/programming/crypto-series-intro.html): proving *who* a party is, as opposed to protecting *what* they send (that's [Key Exchange & Secure Channels](/programming/secure-channels.html)). The two are usually fused in a handshake, but they're separable — and authentication has its own 50-year story worth telling on its own. +Authentication runs in two directions, and they arrived in the opposite order you'd guess. **Server authentication** — your browser proving it's really talking to `google.com` and not an impostor — is the older problem and the one that runs silently on *every* HTTPS connection, login or not; it's the job of the Web PKI. **User (client) authentication** — a human or device proving identity *to* the server — is the visible login step, and its 50-year arc fills most of this post. **Mutual authentication** (mTLS) is just both at once. The [threat-model post](/programming/threat-model.html) named server authentication as "the identity binding" — layer 2, *is this key really Bob's?* — but left the mechanism for here. + ## The actors Authentication is a conversation between a handful of parties — a client, the resource server it's talking to, and often an identity provider that vouches for it — each holding different resident keys and minting different per-request proofs. @@ -16,9 +18,52 @@ Authentication is a conversation between a handful of parties — a client, the > The grammar of what any proof can claim — who (identity: aud, iss, sub, rpId), when (freshness: iat, exp, jti, nonces), what (content: the bytes the proof commits to), what-for (scope), and bound-to-what (chaining: cnf claims) — is laid out in the secret-material map in [Keys](/programming/keys.html). Read any auth scheme below by asking which of those five it covers and which it omits. +## Server Authentication & the Web PKI + +The user-auth story below is about moving the root of trust *out of the server's hands*. Server authentication has the mirror-image arc: moving it *out of any single CA's hands*. A public key is not a name — nothing in the bytes of `google.com`'s public key says "google.com" — so something has to vouch for the binding, and the whole history is about who that voucher is and how much you're forced to trust them. + +You can read an X.509 certificate through the same five-part grammar as any other proof: **who** (the `subject` / Subject Alternative Names — the domains), **when** (the `notBefore`/`notAfter` validity window), **what-for** (key-usage and extended-key-usage extensions — "this key may sign TLS handshakes, not mint other certs"), and **bound-to-what** (the issuer's signature, chaining the leaf upward). The leaf binds a domain to a key, an intermediate signs the leaf, a root CA signs the intermediate — and the root's public key was baked into your browser or OS out of band, which is the [Roots of Trust](/programming/roots-of-trust-and-attestation.html) story, the anchor every chain terminates at. + +#### Phase 1: Self-signed & TOFU (pre-PKI) + +With no third party to vouch, you either accept a self-signed cert blindly or trust-on-first-use — pin the key the first time you see it and scream if it ever changes. SSH host keys still work exactly this way (`The authenticity of host ... can't be established`). TOFU is genuinely fine when you talk to the same server repeatedly, but it can't bootstrap trust with a server you've never met — which is the entire web. + +#### Phase 2: Hierarchical CAs — X.509 & the Web PKI (1978 →) + +Loren Kohnfelder's 1978 MIT thesis coined the word *certificate*: a signed statement binding a name to a key, so you no longer need an online directory lookup for every party. ITU standardized the format as X.509 (1988; the v3 extensions everyone actually uses arrived in 1996, profiled for the internet as RFC 5280). Netscape wired it into SSL in the mid-90s, and a commercial CA industry grew up to sign certs for a fee. The model: trust a fixed set of root CAs preinstalled in your browser, and transitively trust anything they sign. This is *still* the Web PKI — but notice the trust is blind and global: **any** trusted CA can vouch for **any** domain, so the system is only as strong as its single weakest CA. + +#### Phase 3: Automating issuance — ACME & Let's Encrypt (2015) + +For two decades certs cost money and were issued by hand, so most of the web stayed on plaintext HTTP. Let's Encrypt (ISRG, 2015) made domain-validated certs free and fully automated via the ACME protocol (RFC 8555): prove you control a domain by serving a token at a well-known URL or publishing a DNS record, and a cert drops out — scriptable end to end. HTTPS went from minority to near-universal in a few years. This is the **DV** (domain-validated) tier — "controls the domain," nothing more; the **OV** and **EV** tiers additionally vet the legal *organization*, but browsers quietly stopped giving EV any special UI treatment around 2019, conceding that users never read it. + +#### Phase 4: Auditing the CAs — Certificate Transparency (2013 →) + +Blind global trust broke exactly as you'd expect: the Comodo and DigiNotar compromises (2011) minted valid certs for domains like `google.com`, and nobody could *see* it had happened (the [threat-model post](/programming/threat-model.html) tells that story). Certificate Transparency (RFC 6962) is the fix: every cert must be logged in append-only, publicly-auditable logs, and Chrome and Safari reject certs that don't carry proof of logging. A bogus cert can still be *minted*, but no longer *invisibly* — domain owners monitor the logs for certs they never requested. CAA DNS records (which CAs are even permitted to issue for a domain) and multi-perspective domain validation (check domain control from several network vantage points, so a local BGP hijack can't fool it) are the same move: stop trusting a single CA blindly, constrain and audit it instead. + +#### Phase 5: Shrinking the trust window — short-lived certs + +Revocation is PKI's chronic weak spot — the "stale" problem from the [capstone](/programming/roots-of-trust-and-attestation.html). CRLs (download every revoked serial) grew too big; OCSP (ask the CA live, per connection) leaked your browsing history to the CA and added latency; OCSP stapling (the *server* fetches and attaches a fresh signed status) fixed privacy and latency but was never reliably deployed. The blunt answer that won was to make certs so short-lived that revocation barely matters: maximum lifetimes have ratcheted from 825 days to 398 (Sept 2020), and the CA/Browser Forum has voted to reach 47 days by 2029. A cert that expires in weeks is its own revocation. + +#### The alternatives: who else can vouch? + +Hierarchical CAs aren't the only way to bind a key to an identity. Each alternative is really a different answer to "who vouches, and for what?": + +- **Web of Trust (PGP, 1991).** No CAs — users sign each other's keys, and trust propagates through whoever you've personally chosen as "introducers" (Zimmermann's "decentralized fault-tolerant web of confidence"). Decentralized and human-meaningful, but it never scaled: key-signing parties are friction, and trust paths between strangers are rarely short or legible. +- **SPKI/SDSI (RFC 2693, 1999).** Grew out of frustration with X.509's complexity, and made a radical move: *the key is the principal* — don't bind keys to global real-world identities at all, bind them to **authorizations** and **local names**, with the verifier often also the issuer (an "authorization loop"). Closer in spirit to today's capability tokens (macaroons, biscuits) than to the Web PKI. +- **DANE (RFC 6698, 2012).** Anchor certs in DNSSEC instead of CAs — publish the cert's fingerprint in a DNS record signed up the DNS hierarchy. Trades the CA cartel for the DNS root; browsers never adopted it. +- **Decentralized PKI / key transparency.** Blockchain naming (Namecoin, ENS) and W3C DIDs let each entity act as its own root authority, anchored in a distributed ledger rather than a CA — and the [roots-of-trust](/programming/roots-of-trust-and-attestation.html) post notes a blockchain genesis hash is just one more out-of-band anchor. Meanwhile key transparency (CONIKS, then Google / WhatsApp / iMessage key transparency) applies CT's "log everything" idea to *end-user* keys, so an E2EE provider can't swap in a wiretap key without leaving a public, auditable trace. + +These map cleanly onto Zooko's triangle (secure / human-meaningful / decentralized — pick two, from the [capstone](/programming/roots-of-trust-and-attestation.html)): the Web PKI takes human-meaningful + secure and sacrifices decentralization (you trust the CA cartel); Web of Trust reaches for human-meaningful + decentralized and gives up reliable security at scale; self-certifying names (a Tor `.onion` address, a raw public-key fingerprint) are secure + decentralized but not human-meaningful; and blockchain naming is the bet that a global ledger can finally square all three. + +Notice the throughline — the same one the user-auth arc has below: every step after Phase 2 (CT, CAA, multi-perspective validation, short lifetimes, and every decentralized alternative) pushes the root of trust *out of any single CA's hands*. Server auth and user auth are one de-trusting trajectory pointed in opposite directions. + +#### Mutual TLS + +Everything above authenticates the *server* to the client. mTLS makes it symmetric: the client also presents a cert, and the server validates it against its own trust anchor. On the open web this is rare (users don't carry certs), but it's the backbone of *service-to-service* authentication inside infrastructure — a workload's identity *is* an X.509 cert (SPIFFE/SPIRE issue exactly these), and possession of the matching private key is the proof. Same possession anchor as a passkey, just with no human in the loop — which reconnects to the service-to-service tier of the [security hierarchy](#picking-an-auth-method-security-hierarchy) below. + ## History of User Authentication -The whole history of server-side authentication is the story of moving the root of trust out of the server's hands. The arc is secret-held-by-server → secret-held-by-server-but-harder-to-crack → secret-held-by-client. +The whole history of user authentication is the story of moving the root of trust out of the server's hands. The arc is secret-held-by-server → secret-held-by-server-but-harder-to-crack → secret-held-by-client. #### Phase 1: Plaintext passwords (1960s–70s) @@ -97,6 +142,12 @@ For service-to-service authentication (backend APIs calling each other) — no h 4. [Best Current Practice for OAuth 2.0 Security - RFC 9700][rfc9700] 5. [Grant Negotiation and Authorization Protocol (GNAP) - RFC 9635][rfc9635] 6. [OAuth 2.0 and the Road to Hell - Eran Hammer][hammer-road-to-hell] +7. [Public Key Infrastructure - Wikipedia][pki-wiki] +8. [Internet X.509 PKI Certificate and CRL Profile - RFC 5280][rfc5280] +9. [Automatic Certificate Management Environment (ACME) - RFC 8555][rfc8555] +10. [Certificate Transparency - RFC 6962][rfc6962] +11. [SPKI Certificate Theory - RFC 2693][rfc2693] +12. [DNS-Based Authentication of Named Entities (DANE) - RFC 6698][rfc6698] [morris-thompson]: https://rist.tech.cornell.edu/6431papers/MorrisThompson1979.pdf "Password Security: A Case History - Morris & Thompson (1979)" [sysapproach-auth]: https://book.systemsapproach.org/security/authentication.html "Authentication - Computer Networks: A Systems Approach" @@ -104,3 +155,9 @@ For service-to-service authentication (backend APIs calling each other) — no h [rfc9700]: https://datatracker.ietf.org/doc/html/rfc9700 "Best Current Practice for OAuth 2.0 Security - RFC 9700" [rfc9635]: https://datatracker.ietf.org/doc/html/rfc9635 "Grant Negotiation and Authorization Protocol (GNAP) - RFC 9635" [hammer-road-to-hell]: https://hueniverse.com/oauth-2-0-and-the-road-to-hell-8eec45921529 "OAuth 2.0 and the Road to Hell - Eran Hammer" +[pki-wiki]: https://en.wikipedia.org/wiki/Public_key_infrastructure "Public Key Infrastructure - Wikipedia" +[rfc5280]: https://datatracker.ietf.org/doc/html/rfc5280 "Internet X.509 Public Key Infrastructure Certificate and CRL Profile - RFC 5280" +[rfc8555]: https://datatracker.ietf.org/doc/html/rfc8555 "Automatic Certificate Management Environment (ACME) - RFC 8555" +[rfc6962]: https://datatracker.ietf.org/doc/html/rfc6962 "Certificate Transparency - RFC 6962" +[rfc2693]: https://datatracker.ietf.org/doc/html/rfc2693 "SPKI Certificate Theory - RFC 2693" +[rfc6698]: https://datatracker.ietf.org/doc/html/rfc6698 "DNS-Based Authentication of Named Entities (DANE: TLSA) - RFC 6698"