JWT algorithms compared

The alg header names the JWS algorithm (RFC 7518) used to sign a token. Here is how the twelve common algorithms differ, which keys they need, and how to use them safely.

All algorithms

algFamilyKeySignature
HS256HMAC using SHA-256Shared secret ≥ 256 bits32 bytes
HS384HMAC using SHA-384Shared secret ≥ 384 bits48 bytes
HS512HMAC using SHA-512Shared secret ≥ 512 bits64 bytes
RS256RSA signature (PKCS#1 v1.5) using SHA-256RSA key pair ≥ 2048 bits= key size
RS384RSA signature (PKCS#1 v1.5) using SHA-384RSA key pair ≥ 2048 bits= key size
RS512RSA signature (PKCS#1 v1.5) using SHA-512RSA key pair ≥ 2048 bits= key size
PS256RSA-PSS signature using SHA-256 and MGF1RSA key pair ≥ 2048 bits= key size
PS384RSA-PSS signature using SHA-384 and MGF1RSA key pair ≥ 2048 bits= key size
PS512RSA-PSS signature using SHA-512 and MGF1RSA key pair ≥ 2048 bits= key size
ES256ECDSA using P-256 and SHA-256EC P-256 key pair64 bytes
ES384ECDSA using P-384 and SHA-384EC P-384 key pair96 bytes
ES512ECDSA using P-521 and SHA-512EC P-521 key pair132 bytes

No algorithm on this list is insecure by name. HS256 with a strong random 256-bit secret is perfectly sound; HS256 with the secret "secret" is not. The key and how it is managed matter more than the letters in alg.

Choosing an algorithm

Pin the algorithm

The classic algorithm confusion attack takes a token signed with RS256, changes the header to HS256, and signs it with the server's public key as the HMAC secret. A library that picks the algorithm from the token header and accepts the public key as an HMAC key will accept it. RFC 8725 §3.1 requires verifiers to decide which algorithms are acceptable and to bind each key to one algorithm:

// ✓ algorithm chosen by the verifier
jwtVerify(token, publicKey, { algorithms: ["RS256"] })

// ✗ algorithm chosen by the attacker
jwt.verify(token, key, { algorithms: [decodedHeader.alg] })

The “none” algorithm

alg: "none" means the token is unsigned (RFC 7518 §3.6). It exists for contexts where integrity is guaranteed another way. A verifier must never accept it unless it was explicitly configured to — the decoder flags such tokens prominently.

Paste a JWT to see its algorithm, key ID and signature length checked against the specification.

Check a token's algorithm