15

I'm currently implementing user authentication on a REST-like API that is used by an Android client. After some research I think that JWT (JSON Web Token) is a good way to do it.

The basic procedure I have planned is: The user logs in using username/password (over HTTPS). The server validates the password and then generates a JWT that includes some kind of user ID, signing it with RS256 (asymmetric using RSA, so the client only has the corresponding public key), and sends it to the client. To do an API call, the client will send the JWT to the server. All the server does then is validate the JWT using its private key, and also checking that the signature algorithm is the one expected by the server. If the validation succeeds, the server can trust the user ID in the token. A client can't pretend to be a different user, because it would need the server's private key to generate a correct signature if the JWT's payload is changed.

Now suppose I wanted to use HS256 (symmetric using a HMAC) instead, maybe because the resulting signature is shorter. As far as my common sense goes, in this case, only the server is allowed to know the (single) key.

But here comes the confusion: Reading up on using HS256 with JWTs, some sites I have seen seem to suggest that the key is a "shared secret", meaning that both the server and the client know it. But if that's the case, the client could simply alter the JWT's payload and create a valid signature using the shared key. Any logged-in user could then pretend to be any other user by simply altering the user ID in the JWT, so that's no better than not validating a signature at all. Is there something I'm missing, or does it simply not make sense to allow the client access to the key when using HS256? Have I misread the sites suggesting that the HS256 key is shared?

The only way I could think about that would allow both parties to know the key is using a separate key for each user. But even then, any JWT payload data except the user ID (e.g. an "isAdmin" flag) could still be changed at will.

Alemarius Nexus
  • 253
  • 2
  • 4

1 Answers1

11

"Shared secret" in this case typically means between multiple servers, not between the client and the server. Typically, JWTs can be done using symmetric encryption - in which case all servers that need to verify the token need to have the shared secret - or asymmetric encryption, in which case only the server actually doing the authentication needs to have the private key, the other servers can just use the public key to verify that the token is appropriately signed.

In no case should a client have the ability to alter their token - they receive the token upon presenting credentials, then use the token to obtain services, either from the same server, or from other servers who share a trust relationship with the authorizing server (either through the public/private key knowledge or through a shared key)

crovers
  • 6,311
  • 1
  • 19
  • 29