0

I have angular on frontend and PHP on backend in my web site. I am using this library to create a JWT:

I create the token on the server like this:

$jwt = JWT::encode($payload, JWT_SECRET_KEY);

It has a secret key with which you create the JWT and then it is being checked on any subsequent call to the API, which makes sense. However, I went to jwt.io and just pasted in the JWT and jwt.io was able to decypher it correctly and display the payloads. I don't want this to happen, since that would mean that anyone can just create that token himself and authenticate against the server. What am I doing wrong here, does anyone know?

IMSoP
  • 65,743
  • 7
  • 83
  • 127
Vladimir Despotovic
  • 2,417
  • 2
  • 26
  • 46
  • 1
    Do you encrypt your JWT token? – Justinas Jan 18 '21 at 14:13
  • @Justinas no, but that is not in the description in the git repo. How should I encrypt it? – Vladimir Despotovic Jan 18 '21 at 14:14
  • 1
    There are plenty of tools to encrypt your data – Justinas Jan 18 '21 at 14:15
  • @Justinas ok. thanks. – Vladimir Despotovic Jan 18 '21 at 14:16
  • @Justinas do you know why am I doing then anything in this JWT encoding (secret key and then encode using secret key) when it is completely decodable? This is bugging me. – Vladimir Despotovic Jan 18 '21 at 14:19
  • 1
    *that would mean that anyone can just create that token himself* - no, as long as the key is kept secret, you can't create a valid signature – jps Jan 18 '21 at 14:19
  • Ok, my bad there, but anyone can decode it and see the payload (see my above comment). – Vladimir Despotovic Jan 18 '21 at 14:19
  • 2
    JWTs come in two flavours: _signed_ (anyone can _read_, but only the owner of the private key can _write_) and _encrypted_ (anyone with the public key can _write_, but only the owner of the private key can _read_). There are different use cases for each, and that library happens to only support the _signing_ use case. You can also wrap one in the other to get both benefits. – IMSoP Jan 18 '21 at 14:20
  • 1
    The information is in the token and is passed through the client; even if it *is* encrypted, the mere fact that it contains "secrets" makes it a target. So a determined attacker could *try* to brute-force the token at their leisure. So it's questionable what sort of *secrets* you'd want to store in a token in the first place, if there's even a remote possibility that they *can* be revealed. As such, does it really *matter* that the token is readable, as long as it's not *spoofable*? – deceze Jan 18 '21 at 14:27
  • So where does the secret key that I use to encode the JWT comes in? If anyone can just read the JWT (decode it). – Vladimir Despotovic Jan 18 '21 at 14:57
  • 1
    But they can't *spoof* it. The token is *signed* with the secret key, and when you decode the token, you're *verifying the signature*. Only somebody in possession of the secret key can create a valid signature. Invalid signatures will/should be rejected by the JWT library with an exception. – deceze Jan 18 '21 at 15:06
  • Ok, so the library actually does have a way to see more things than that site jwt.io. I don't know how this works then. I did, admittedly, try to decode the JWT using different secret key than the original one, and it fails. But this is done in the JWT PHP library (firebase). Is this the correct way? The PHP library should actually see more decoded data than jwt.io? – Vladimir Despotovic Jan 18 '21 at 15:16
  • You're still confusing _secrecy_ with _verifiability_. There isn't some extra data encoded that only you can see, there's just a signature, and a way to verify that signature. It's just like a real-life signature:if you sign a contract, it doesn't add secret information, it just lets anyone who's got a sample of your signature verify that it was really you who signed it. Via the magic of maths, digital signatures are a bit stronger than that - they prove that the data is still _exactly the same_ as when you signed it - but all they're doing is say "yes" or "no" to that question. – IMSoP Jan 18 '21 at 16:02
  • @deceze If the NSA is going to log into your site and decode your JWT by bruteforcing a properly implemented asymmetric encryption, then I'd be interested to know what you're up to. For everyone else in the world, it's most decidedly not an issue, and while in most cases verifiability is the more important property, there are definitely use cases for including details in a JWT that you don't want the user to be able to read directly. – IMSoP Jan 18 '21 at 16:07
  • What I was actually interested in is why can that JWT library verify more data than jwt.io site. That JWT library has some secret code and it fails if the JWT token doesn't "comply". The jet.io website can't do that. Why is this? The jwt.io already can see the payload. What is then the purpose of the JWT library to check some secret, which the jwt token does have, but why this functionality? – Vladimir Despotovic Jan 18 '21 at 16:37
  • 1
    There is nothing secret! The key is to check that the signature is valid, nothing more, nothing less; it's like your bank having your signature on file so they can detect if someone's pretending to be you. Try this: encode a JWT with the payload `{"godmode":false}` and check that you can decode it with the same private key. Now edit that JWT by hand to change it to `{"godmode":true}` but don't change anything else. Anyone can see that you've **tried** to give yourself god mode, but the library will tell you that the signature is invalid, and the token should not be trusted. – IMSoP Jan 18 '21 at 16:59

0 Answers0