CodeOath
← All posts
Auth & Security60 min total · 19 parts

OAuth 2.0 and JWT Explained: How "Login with Google" Actually Works

Contents — Part 10 of 19: JWT Signing Algorithms: HMAC vs. RSA/ECDSA
Part 10 of 19 · ~2 min

JWT Signing Algorithms: HMAC vs. RSA/ECDSA

The alg field in a JWT's header determines the mathematics behind its signature, and the two families you'll encounter behave very differently for a multi-service system.

HMAC (HS256, HS384, HS512) is symmetric — the same secret key both signs and verifies the token. Simple to set up, but every service that needs to verify tokens must also possess the actual signing secret, which means every one of those services could also forge valid tokens. That's an acceptable trade-off for a single monolithic backend, and a real liability the moment multiple independent services need to verify tokens issued elsewhere.

RSA/ECDSA (RS256, ES256, and similar) are asymmetric — a private key signs, and a separate public key verifies. The private key stays on the authorization server alone; any number of resource servers can be handed the public key (often published at a well-known JWKS endpoint) to verify tokens without ever being able to forge new ones themselves.

HMAC (HS256)RSA/ECDSA (RS256/ES256)
Key typeOne shared secretPrivate key (signs) + public key (verifies)
Who can verifyAnyone with the shared secretAnyone with the public key
Who can forge a tokenAnyone who can verify itOnly the holder of the private key
Best fitA single backend issuing and checking its own tokensMultiple independent services verifying tokens from one central issuer

This distinction is also the root of a real, documented vulnerability class: some early JWT libraries, when told to verify a token, would trust the alg field from the token itself — so an attacker could take a legitimately RS256-signed token, strip the signature, change alg to HS256, and re-sign it using the public key (which is, by definition, public) as if it were an HMAC secret. A naive verifier configured to "accept whatever algorithm the token claims" would then wrongly validate it. The fix, covered next, is for verification code to pin the expected algorithm itself rather than trusting the token to say what algorithm was used to sign it.