Authentication
Authentication verifies that an entity (user, service, device) is who it claims to be. It answers the question: "Who are you?" -- distinct from authorization ("What are you allowed to do?").
Authentication Factors
Something you know (password, PIN), something you have (phone, hardware key), something you are (fingerprint, face). Multi-factor authentication (MFA) combines two or more factors.
Password-Based Authentication
Password Storage
Never store plaintext passwords. A breach exposes every account.
Hashing: Store H(password). Verify by comparing H(input) to the stored hash. Problem: identical passwords produce identical hashes -- vulnerable to rainbow table attacks.
Salting: Store (salt, H(salt || password)). The salt is a random value unique per user (typically 16+ bytes). Rainbow tables become useless since each password has a different salt.
Key stretching: Use a slow hash function (Argon2id, bcrypt, scrypt) to make brute-force attacks expensive. A single SHA-256 hash takes nanoseconds; Argon2id with proper parameters takes 100+ milliseconds.
PROCEDURE HASH_PASSWORD(password) → string
salt ← GENERATE_RANDOM_SALT()
hash ← ARGON2ID_HASH(password, salt)
RETURN hash AS string
// Output: $argon2id$v=19$m=19456,t=2,p=1$salt$hash
PROCEDURE VERIFY_PASSWORD(password, hash) → boolean
parsed ← PARSE_HASH(hash)
RETURN ARGON2ID_VERIFY(password, parsed) IS success
Common Password Attacks
- Brute force: Try all combinations. Mitigated by rate limiting, account lockout, slow hashing.
- Dictionary attack: Try common passwords. Mitigated by password complexity requirements and breach databases (Have I Been Pwned).
- Credential stuffing: Use credentials leaked from other sites. Mitigated by MFA and breach detection.
- Phishing: Trick user into entering password on a fake site. Mitigated by FIDO2/WebAuthn.
Multi-Factor Authentication (MFA)
TOTP (Time-Based One-Time Password)
RFC 6238. Generates a 6-digit code from a shared secret and the current time:
TOTP = HMAC-SHA1(secret, floor(time / 30)) mod 10^6
30-second window. Shared secret provisioned via QR code. Apps: Google Authenticator, Authy. Phishable -- an attacker can relay the code in real time.
FIDO2 / WebAuthn
Phishing-resistant authentication using public-key cryptography.
Registration: The authenticator (hardware key or platform authenticator) generates a key pair. The public key is registered with the server. The private key never leaves the authenticator.
Authentication: The server sends a challenge. The authenticator signs it with the private key, binding the signature to the origin (domain name). A phishing site on a different domain cannot obtain a valid signature.
Server → Browser: challenge, rpId="example.com"
Browser → Authenticator: challenge, origin="https://example.com"
Authenticator → Browser: signature(challenge), credential_id
Browser → Server: assertion (verified with stored public key)
Passkeys: FIDO2 credentials synced across devices (via iCloud Keychain, Google Password Manager). Replaces passwords entirely.
OAuth 2.0
An authorization framework (not authentication) that allows third-party applications to access resources on behalf of a user without sharing credentials.
Roles
- Resource Owner: The user.
- Client: The application requesting access.
- Authorization Server: Issues tokens (e.g., Auth0, Okta).
- Resource Server: Hosts the protected API.
Authorization Code Flow (with PKCE)
The recommended flow for web and mobile apps:
1. Client generates code_verifier (random) and code_challenge = SHA256(code_verifier)
2. Client redirects user to Authorization Server:
/authorize?response_type=code&client_id=...&redirect_uri=...
&code_challenge=...&code_challenge_method=S256
3. User authenticates and consents
4. Authorization Server redirects back with authorization code
5. Client exchanges code + code_verifier for tokens:
POST /token { grant_type=authorization_code, code=..., code_verifier=... }
6. Authorization Server returns: { access_token, refresh_token, id_token }
PKCE (Proof Key for Code Exchange) prevents authorization code interception attacks. Required for all clients (RFC 9126).
Token Types
- Access token: Short-lived (minutes to hours). Sent with API requests. Often a JWT.
- Refresh token: Long-lived. Used to obtain new access tokens without re-authentication. Store securely (server-side or encrypted).
- ID token: OpenID Connect addition. Contains user identity claims.
OpenID Connect (OIDC)
An identity layer on top of OAuth 2.0. Adds authentication semantics.
ID Token: A JWT containing claims about the authenticated user:
{
"iss": "https://accounts.google.com",
"sub": "110169484474386276334",
"aud": "client-id-here",
"exp": 1716239022,
"iat": 1716235422,
"nonce": "random-value",
"email": "user@example.com",
"email_verified": true
}
UserInfo Endpoint: /userinfo returns additional claims about the authenticated user.
Discovery: /.well-known/openid-configuration provides metadata (endpoints, supported algorithms, etc.).
SAML (Security Assertion Markup Language)
XML-based federation protocol. Common in enterprise SSO.
1. User accesses Service Provider (SP)
2. SP redirects to Identity Provider (IdP) with SAML AuthnRequest
3. User authenticates at IdP
4. IdP sends signed SAML Assertion (XML) back to SP via browser POST
5. SP validates signature, extracts attributes, creates session
SAML vs OIDC: SAML uses XML (verbose, complex signature validation). OIDC uses JSON/JWT (simpler, better for APIs and mobile). SAML is legacy but deeply entrenched in enterprise. New systems should prefer OIDC.
Kerberos
Network authentication protocol using a trusted third party (Key Distribution Center). Used in Active Directory.
1. AS-REQ: Client → KDC: "I am Alice" (encrypted with password-derived key)
2. AS-REP: KDC → Client: TGT (Ticket-Granting Ticket, encrypted with KDC's key)
3. TGS-REQ: Client → KDC: TGT + "I want to access FileServer"
4. TGS-REP: KDC → Client: Service Ticket (encrypted with FileServer's key)
5. AP-REQ: Client → FileServer: Service Ticket
6. FileServer decrypts ticket, authenticates Alice
Key properties: Password transmitted only once (step 1). Mutual authentication. Tickets have limited lifetime. Single sign-on (TGT reused for multiple services).
Attacks: Pass-the-ticket, golden ticket (forged TGT using compromised KDC key), Kerberoasting (requesting service tickets to crack offline).
JSON Web Tokens (JWT)
A compact, URL-safe token format. Three Base64URL-encoded parts separated by dots:
Header.Payload.Signature
Header: {"alg": "RS256", "typ": "JWT"}
Payload: {"sub": "1234", "name": "Alice", "exp": 1716239022}
Signature: RSA-SHA256(base64url(header) + "." + base64url(payload), private_key)
JWT Security Considerations
- Always validate: signature, expiration (exp), issuer (iss), audience (aud).
- Algorithm confusion: Never accept "alg": "none". Validate the algorithm server-side.
- Use asymmetric signatures (RS256, ES256) for distributed verification. HMAC (HS256) requires sharing the secret with every verifier.
- Keep payloads small: JWTs are not encrypted by default (use JWE if confidentiality is needed).
- Revocation: JWTs cannot be revoked before expiration. Use short expiry + refresh tokens, or maintain a revocation list.
Session Management
Server-Side Sessions
Server stores session state, client holds only a session ID (in a cookie).
Set-Cookie: session_id=abc123; HttpOnly; Secure; SameSite=Strict; Path=/
Cookie attributes:
- HttpOnly: Not accessible via JavaScript (prevents XSS theft).
- Secure: Only sent over HTTPS.
- SameSite=Strict: Not sent with cross-site requests (CSRF protection).
- Path=/: Scope to the entire application.
Session Security
- Generate session IDs with a CSPRNG (at least 128 bits of entropy).
- Regenerate session ID after authentication (prevents session fixation).
- Set absolute and idle timeouts.
- Invalidate server-side on logout (delete the session record).
- Bind sessions to additional context (IP address, User-Agent) for anomaly detection.
Stateless vs Stateful Sessions
Stateful (server-side sessions): Easy to revoke. Requires shared session store in distributed systems (Redis, database).
Stateless (JWT): No server-side storage. Scales horizontally. Difficult to revoke. Larger cookie size. Suitable for short-lived API tokens.
Real-World Architecture
A modern authentication system typically combines several of these mechanisms:
- Primary authentication: Password + TOTP/WebAuthn (MFA).
- Token issuance: OAuth 2.0 Authorization Code flow with PKCE.
- API authentication: JWT access tokens with short expiry.
- Session management: Server-side sessions for web UI, JWT for API.
- Federation: OIDC for consumer apps, SAML for enterprise SSO.