Reputation: 19574
I'm sure I'm missing something very simple here, but I just started learning about JWT tokens for authenticating and, as I understand it, the structure of a JWT token is:
Base64UrlEncode(Header) + '.' + Base64UrlEncode(Payload) + '.' + CreateSignature(Header, Payload, Secret_Key)
And what I'm understanding is that you send this to the client and it allows the client to send this back to the server when needed. At which point you decrypt the Signature to make sure it wasn't tampered with using your private key.
The part I'm confused about is why you need the first part of Base64UrlEncode(Header) + '.' + Base64UrlEncode(Payload) + '.'
which is easily converted back to plain-text, then?
Since you will be decrypting it on the server, couldn't you just pass the signature, decrypt it using your secret key and read the payload whereas no one else could?
It seems like this would be safer since the first part can be easily converted back to plain-text and give an attacker information such as token expiration
, userId
and the like that is stored in the payload.
What am I missing?
Upvotes: 3
Views: 2059
Reputation: 15599
The signature does not contain the payload. The signature can be as simple as a message authentication code (HMAC) of the hash (SHA256) of the jwt. So if you only sent the signature, that would work as a plain old session id, and the server would still have to store state, negating any benefit of a jwt.
You are right though, a jwt by default is not encrypted. While encoded with base64, from a security perspective it's just plain text and should not contain sensitive (secret) information. The only protection the signature provides is that when the server receives it back, it can make sure by checking the signature that the information in the jwt was not altered on the client.
The token not being encrypted allows the client to inspect its contents and figure out for example the expiry time, when it will have to obtain a new token, or the logged in user's id. The user who has the jwt would have this kind of information anyway, and others are not supposed to have the jwt, because they could use it for authentication to impersonate the user.
However, under special circumstances, you may still want to include sensitive info (ie. secrets) that you want to receive back on the server but don't want to disclose to the client. For that you can use an encrypted jwt (jwe). The drawback is that this token will be opaque for the client and you will probably have to implement application endpoints to retrieve all necessary information.
Upvotes: 2