5 ms·
Brute forcing JSON Web Tokens in C
- davewritescode 10y agoA good reminder to use long HMAC secrets or sign your JWT with RSA.
- brendanrius 10y agoDefinitely, you would be surprised by the amounts of JWT using very simple secrets
- porpoisemonkey 10y agoYeah - that's unfortunate. The spec clearly outlines a required minimum key length and it could be easily enforced in JWS libraries to make things more secure.
- spydum 10y agoI 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 10y agoIt makes rotating the secret a hell of a lot easier as well.
- lvh 10y agoI'm not sure I follow. You still need to communicate the public key securely.
- deleted 10y ago[deleted]
- crgwbr 10y agoWe use RSA signed JWTs for quite a few services and it's been a joy so far. Makes key rotation without downtime super easy and (obviously) doesn't have any of the dangers associated with a shared secret. https://github.com/crgwbr/asymmetric_jwt_auth https://github.com/crgwbr/asymmetric_jwt_auth
- nrjdhsbsid 10y agoSigning jwt with RSA is a bad idea. Asymmetrical encryption methods are orders of magnitude slower than hmac. It sounds like a nice thing to do but it's really really slow compared to hmac. That's why TLS only uses the public key to exchange a symmetric key then switches over to AES or whatever.
- tscs37 10y agoJWT with RSA or Ed25519 is definitely not a bad idea there.
- lvh 10y agoJWT does not define Ed25519 as part of the spec. It is supported "off-label" in one JWT library I could find (Joken) for a relatively uncommon language (Elixir). Frustratingly, JWT defines a tons of stuff, where few are required but some are "Recommended" and some are "Recommended+". I'm not sure what "Recommended+" means, but apparently it means "has known cryptographic flaws", because RSA with PKCSv15 padding is "Recommended+".
- tscs37 10y agoI kinda went over the standard on that. The Go library I use allows to define custom algorithms, so I just set alg to ED2 and use it. It's within the app only so it doesn't hurt much. Also agree, it's rather frustrating that JWT is so well defined but something as simple as using Ed25519 is not part of the standard yet.
- buckhx 10y agoES256 is in the spec at least
- CiPHPerCoder 10y ago
- deleted 10y ago[deleted]
- milad_nazari 10y agoI'm curious. How long could it take to bruteforce a JWT with an average latest generation i7 processor?
- vpol 10y agoToo long to waste time.
- brendanrius 10y agoDepends on the secret
- Freak_NL 10y agoDepends on the signing cypher or hash used. With SHA-256 or an RSA 2048 bit key pair this is not a vulnerability to be concerned about.
- wongarsu 10y agoSince 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/a83d38f412b4737e99bbef804a270c40 https://gist.github.com/epixoip/a83d38f412b4737e99bbef804a27...
- porpoisemonkey 10y agoThis 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 10y agoIf only people respected RFCs
- andrewstuart2 10y agoI'm not aware of any common libraries that don't. Where did you get the token cracked in your example code?
- niftich 10y agoLet'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
- brendanrius 10y agoI generated this one with jwt.io, but after testing it looks like pyjwt (which is a very common library) does exactly the same thing
- merb 10y agoactually 256-bit key size is not a "big" burden for people. I've seen lots of JWT implementationens which use key sizes > 1024 bits. Consider the Mime64 encoded Bit String: > 8Jbr+vX5JpFZOW7P1RLs7/ArYy1Az7hrimMfcI3qqBI= This "small" Key is already 256-Bit. if decoded to an Array in Java: > java.util.Base64.getDecoder.decode("8Jbr+vX5JpFZOW7P1RLs7/ArYy1Az7hrimMfcI3qqBI=").length * 8 > res7: Int = 256 if you try to decode a jwt with it, it takes forever. (Actually I guess you also need to raise the length of the progam but it's akward since you probably don't know the correct length. Actually I use HMAC-SHA512 with key sizes between 1024-Bit to 2048-Bit. Edit: Typo
- psiclops 10y ago'Brute forcing JSON Web Tokens tokens in C'
- brendanrius 10y agoIt's clearer, I fixed it :)
- jsd1982 10y agoThis 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.
- eosrei 10y agoThe JWT example in the readme works, but another valid JWT does not. Ubuntu 16.04.
- brendanrius 10y agoThat 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 10y agoIt 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.
- chias 10y agoNice! For a threaded Rust implementation, see https://github.com/ojensen5115/jwtcrack https://github.com/ojensen5115/jwtcrack
- brendanrius 10y agoNice work, thanks for sharing
- sigi45 10y agoFind it wasteful to even post this. I'm sry but it was a waste of my time and probably of everyone else reading it. There is no talk about which method is used, supported, what effect key length etc. has. It is even harmful: Perhaps someone is playing around with it and uses energy for running it. Bad for our climate :P
- eddieroger 10y agoThe same could be said about your comment. You spent more time telling the rest of us why it was uninteresting than you think the original link warranted.
- sigi45 10y agoMy comment was more informative than the github project itself. I told what relevant information is even needed and is missing. I'm suprised that i can't downvote an link, instead i wrote a comment.
- scandox 10y agoI 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.
- porpoisemonkey 10y agoIf you sign a JWT with the 5 character secret does it generate a token that you can verify with the 64 character secret? I'm wondering if it could be a key collision.
- scandox 10y agoI couldn't no. Made sure I was using everything the same, but I couldn't determine any relationship between original secret and one produced by program. However contrary to my original statement it turned out secret in use was actually only 30 characters long. I've passed on more detailed info to OP.
- porpoisemonkey 10y agoThanks for checking. > However contrary to my original statement it turned out secret in use was actually only 30 characters long. I'm guessing it's 32 characters long? (256 bits) That matches to the spec and is a good key - as referenced in other threads anything longer is mostly a waste as the key input gets hashed down to a fixed size.
- brendanrius 10y agoIf 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
- deleted 10y ago[deleted]
- scandox 10y agoSent you an email on this. Sorry for slow response.
- arnarbi 10y ago"... 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 10y agoFrom 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