jwt_cracker is a command-line tool for auditing weak secrets in HMAC-signed JWTs. It can test one or many JWT tokens against one or many candidate secrets from direct input, files, or stdin.
The same weak-secret audit can also be performed directly with hashcat. Save the JWT token to jwt.hash, put candidate secrets in jwt-secrets.txt, then run:
hashcat -m 16500 -a 0 jwt.hash jwt-secrets.txt --status --status-timer=10Show cracked results:
hashcat -m 16500 jwt.hash --showUse this tool only on systems, applications, and tokens that you own or have explicit permission to test. Do not use jwt_cracker against third-party services, production systems, or user data without written authorization. You are responsible for complying with all applicable laws, policies, and engagement rules.
- Supports
HS256,HS384, andHS512. - Accepts JWT tokens from a direct string, a line-oriented file, or stdin.
- Accepts secret candidates from a direct string, a line-oriented file, or stdin.
- Streams large secret dictionaries instead of loading the full file into memory.
- Uses multiple worker threads for faster cracking.
- Emits successful matches as soon as they are found.
- Supports optional candidate transforms:
none,base64,md5, andmd5_len16. - Handles non-UTF-8 dictionary entries.
Download a prebuilt binary from the GitHub Releases page when available.
To build from source:
git clone <repo-url>
cd jwt_cracker
cargo build --releaseThe binary will be available at:
target/release/jwt_crackerTest one token with one secret:
jwt_cracker -t '<jwt-token>' -k 'secret'Test tokens from a file against a dictionary:
jwt_cracker -t ./tokens.txt -k ./wordlist.txt -w 8Read secret candidates from stdin:
cat ./wordlist.txt | jwt_cracker -t ./tokens.txt -k - -w 8Apply a candidate transform before testing:
jwt_cracker -t ./tokens.txt -k ./wordlist.txt -e md5_len16 -w 8Usage: jwt_cracker [OPTIONS] --jwt-token <JWT_OR_FILE_OR_STDIN> --secret-key <KEY_OR_FILE_OR_STDIN>
Options:
-t, --jwt-token <JWT_OR_FILE_OR_STDIN>
JWT token, path to a line-oriented token file, or '-' to read tokens from stdin
-k, --secret-key <KEY_OR_FILE_OR_STDIN>
Secret key, path to a line-oriented key file, or '-' to read keys from stdin
-e, --encode-method <METHOD>
Encode each candidate secret before cracking
[default: none]
[possible values: none, base64, md5, md5_len16]
-w, --workers <N>
Number of worker threads to split the total attempt space across
-h, --help
Print help
-V, --version
Print version
Token files should contain one JWT per line:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
eyJhbGciOiJIUzM4NCIsInR5cCI6IkpXVCJ9...
Secret files should contain one candidate per line:
secret
password
hello_world,hello,rust!
- can be used for either tokens or secrets, but not both at the same time.
Successful matches are printed immediately:
MATCH token=<jwt> key=<secret>
When no match is found:
No matching secret keys found.
Progress and final attempt statistics are printed to stderr:
Loaded 1 token(s) from file and 14344400 key(s) from file.
Tested 14344400 total attempt(s) across 8 worker(s) in 3.421s.
jwt_cracker currently supports HMAC-signed JWTs:
HS256HS384HS512
Asymmetric algorithms such as RS256 and ES256 are not supported.
Run the test suite:
cargo testRun formatting and lint checks:
cargo fmt --check
cargo clippy --all-targets -- -D warningsRun benchmarks:
cargo benchIssues and pull requests are welcome. Please keep changes focused, include tests for user-facing behavior, and avoid committing large wordlists or private tokens.
Thanks to alwaystest18/jwtCracker for inspiration.
This project is licensed under the terms in LICENSE.