
Brute forcing JSON Web Tokens in C - brendanrius
https://github.com/brendan-rius/c-jwt-cracker
======
porpoisemonkey
This software attempts to determine the private key for the HMAC-SHA256
(HS256) signature algorithm.

The example provided has a private key length of 32 bits which is far too
short to be secure. Based on the JSON Web Algorithms (RFC 7518) the key length
must be at least the length of the output hash (256 bits) to be used in
accordance with the standard.

> A key of the same size as the hash output (for instance, 256 bits for
> "HS256") or larger MUST be used with this algorithm.

[https://tools.ietf.org/html/rfc7518](https://tools.ietf.org/html/rfc7518)

~~~
brendanrius
If only people respected RFCs

~~~
andrewstuart2
I'm not aware of any common libraries that don't. Where did you get the token
cracked in your example code?

~~~
niftich
Let's suppose I search for 'jwt' and end up at 'jwt.io' (run by Auth0), which
talks about what JWT is and lists a bunch of libraries. Let's say I want to
use python.

One library checks for key lengths [1] and throws exceptions, another one
doesn't [2] -- in fact it uses a quickstart example that should obviously
fail.

[1]
[https://github.com/latchset/jwcrypto/](https://github.com/latchset/jwcrypto/)
[2] [https://github.com/mpdavis/python-
jose](https://github.com/mpdavis/python-jose)

------
chias
Nice! For a threaded Rust implementation, see
[https://github.com/ojensen5115/jwtcrack](https://github.com/ojensen5115/jwtcrack)

~~~
brendanrius
Nice work, thanks for sharing

------
davewritescode
A good reminder to use long HMAC secrets or sign your JWT with RSA.

~~~
spydum
I am curious why more folks don't use rsa keys anyways? Seems like that makes
signature validation even easier (publish the location of the public key for
validation). Then your endpoints don't need to exchange secrets at all?

~~~
davewritescode
It makes rotating the secret a hell of a lot easier as well.

~~~
lvh
I'm not sure I follow. You still need to communicate the public key securely.

------
jsd1982
This doesn't seem to work. Compiled from source on macOS Sierra 10.12.2. I
tried a valid JWT and it reports back instantly that the key is 'e'. Also does
the same with invalid JWT.

~~~
brendanrius
That is definitely strange, if it is not sensitive data, would you mind
sharing the JWT and the original secret? or try to find another example where
it behaves like this?

Thanks

~~~
jsd1982
It is sensitive data so I can't share the payload for a (possibly unfounded)
fear of brute-forcing the correct key used. I can tell you that the key is not
an ASCII string (it is a random sequence of bits). The jwt.io debugger
verified the signature when I gave it the proper key and failed to verify with
the key "e" that this tool reported.

------
psiclops
'Brute forcing JSON Web Tokens tokens in C'

~~~
brendanrius
It's clearer, I fixed it :)

------
milad_nazari
I'm curious. How long could it take to bruteforce a JWT with an average latest
generation i7 processor?

~~~
wongarsu
Since brute forcing the HMAC is pretty much the same as brute forcing the
underlying hash function, you would probably want to use a GPU instead of your
i7.

Using [1] as a reference for a specialised system in a price range affordable
to hobbyists, assuming HMAC-SHA256, a 48bit secret would take about three
hours to brute force (48bit is about 10 letters all lowercase), while a 64bit
secret would already hold 25 years (assuming no upgrades etc).

With sufficient volume you can probably build such a system for about
$5000-$7000. Let's assume $5000, because that number is rounder. If you spend
$1,000,000 on your setup (so certainly professional level now), your 64bit
secret only holds 44 days.

If the NSA would spend 10% of a single year's budget on GPUs, the resulting
machine could crack a 64 bit secret in one hour, but a 84bit secret would take
100 years to crack (84 bits is about 17 lowercase letters, or 14 mixed-case,
or 10.5 bytes if you use the entire range of the byte).

Of course that ignores some scaling effects (if you spend $1billion you get
much more bang for the buck by designing custom ASICs), but it should give a
sense of what's secure against whom. By using proper 256bit secrets you should
be secure against everyone until the end-of-life of your application.

1:
[https://gist.github.com/epixoip/a83d38f412b4737e99bbef804a27...](https://gist.github.com/epixoip/a83d38f412b4737e99bbef804a270c40)

~~~
milad_nazari
Wow. Thanks, I learned a lot from this.

------
arnarbi
"... with 32 bit keys."

The whole thing is editorialized to make it sound like the problem is with
JWTs. It's not, this is just plain old improper use of perfectly good crypto.

Brute-forcing 32 bit HMAC keys isn't exactly newsworthy.

~~~
brendanrius
From the readme: "If you are very lucky or have a huge computing power"

Also the title "Brute forcing JWT in C" could not be clearer. This is not
"0day found in JWT", or just "breaking JWT". This is brute force & nothing
more

This is actually editorialized to make it sound the way it really is

------
scandox
I ran it against some JWTs produced by one of my systems and it reported
success. The secret it gave was about 5 characters in length. The secret we
actually use is 64 characters in length.

~~~
brendanrius
If it is not sensitive information, I would be curious to know the JWT you
tested with, the key used, and the key that program found

~~~
scandox
Sent you an email on this. Sorry for slow response.

