37

I am going to apply JWT into my REST API developed using Java-Jersey. I am using this library for JWT - https://github.com/auth0/java-jwt

I have few questions about the JWT - Secret

  1. Does this Secret has to be unique?
  2. Shall I use the hashed version of user's password for secret? (Then it is not unique anyway) This is because then when user changed his password, his token will be automatically invalid.
PeakGen
  • 21,894
  • 86
  • 261
  • 463

3 Answers3

34
  1. Does this Secret has to be unique?

It should be unique to your application — it needs to be a secret, after all — but it won't be unique for each token. Rather, you should have a relatively small number of secret keys at any given time (e.g., usually having just one key, but having brief periods where you have two keys as you rotate from one to the next).

  1. Shall I use the hashed version of user's password for secret?

No, for two reasons:

  1. Suppose that your user has a relatively insecure password, like GoPackers123. Using the password in your secret then means that someone can easily test a given potential password to see if it results in the right signature; and, more to the point, they can easily test huge numbers of potential passwords to see if any of them gives the right signature. This is an offline attack, so you would never even know it happened.
  2. This would require you to distribute all of your users' password hashes to every system that needs to hold the secret. If you have more than a trivial number of users, this can become a pretty serious burden on your secret-distribution mechanism.
ruakh
  • 175,680
  • 26
  • 273
  • 307
  • 1
    `usually having just one key` - Can I have just one key? I mean for everyone, forever? Or did you mean each user need to have a one key assigned until they logout, but 100 users at that time will have 100 keys?. Also the last question, 2 people having the same secret can bring into a conflict and person `A` will see person `B` records and so on? – PeakGen Mar 16 '17 at 06:37
  • 2
    @PeakGen: You won't share the secret with the user, so you don't need to have different secrets for different users. But you do need to change the key every so often; you can use one key *for everyone*, but not one key *forever*. – ruakh Mar 16 '17 at 15:55
  • Thanks, another question. I was using a **one** hard coded `secret` with the `HS256` in `java-jwt`. I noticed all of my users are getting the same `token`. The api is secured with this token. This is the normal behavior right? – PeakGen Mar 23 '17 at 09:47
  • 2
    @PeakGen: Separate questions should be posted separately, but in brief: no, that's not normal. Your tokens should include claims like `exp` and `sub` to limit lifetime and distinguish users; so no two tokens should be the same. – ruakh Mar 23 '17 at 17:10
18

JWT and the java-jwt library support both symmetric and asymmetric algorithms for the signature:

  • If you go for symmetric algorithms such as HS256, you will have only a single key to be used to sign and verify the signature.

  • If you consider asymmetric algorithms such as RS256, you will have a private and a public key. Keep the private key safe on the server and use it to sign the token. Use the public key to verify the signature (it also can be shared with whoever needs to verify the signature).

Never ever share the key used to sign the token!

And nothing stops you from having a set of different keys for signing your tokens. In this situation, the kid header parameter can be used to indicate which key was used to sign the token. This claim is supposed to carry a key identifier and not the key itself.

Refer to this answer for more details on the kid claim.

Community
  • 1
  • 1
cassiomolin
  • 124,154
  • 35
  • 280
  • 359
  • OK, which one is best? `HS256` or `RSA256 ` – PeakGen Mar 22 '17 at 06:00
  • 3
    @PeakGen The question should be: _Which one is the best for my application?_ And the answer will be: _It depends on your requirements_. If you want to allow the clients to verify the signature, go for RS256. Otherwise, stick to HS256. This [answer](http://stackoverflow.com/q/39239051/1426227) may be helpful. – cassiomolin Mar 22 '17 at 08:16
  • @PeakGen Let me know if you need any further clarification. – cassiomolin Mar 23 '17 at 09:35
  • Thanks. I believe HS256 is the way for me to go as I do not provide any key to user and they have no use of such key as well. Thanks, another question. I was using a **one** hard coded `secret` with the `HS256` in `java-jwt`. I noticed all of my users are getting the same `token`. The api is secured with this token. This is the normal behavior right? – PeakGen Mar 23 '17 at 09:49
  • @PeakGen What do you mean by _all of my users are getting the same token_? – cassiomolin Mar 23 '17 at 09:57
  • The token is generated when the user logs in. I am using the same `secret` with `HS256`. There are 10 users. System generated the same token for everyone when they logged in because the secret was same. I believe this is the normal way? – PeakGen Mar 23 '17 at 10:00
  • @PeakGen No! Something may be wrong. Even with the same secret you are supposed to have different tokens for each user. Otherwise how will you know which user is making the request? For example, you could add a claim to the payload with the username you issued to token for. – cassiomolin Mar 23 '17 at 10:16
  • Thanks, Can you please check here, I made another question on this - https://stackoverflow.com/questions/42974472/jwt-is-issuing-the-same-token\ – PeakGen Mar 23 '17 at 11:40
  • Why not just use a random number? [a] you don't have to configure it, [b] if the server restarts, all JWTs are invalidated. – PeterT Feb 02 '18 at 19:18
2

Use RSA256 i.e. a private/public key-pair (no 'secret' required). That way you can keep the private key secret and safe (it will only be used to sign the token) and you can use the public key to verify that the signature is correct.

You can give the public key to anyone or any service that needs to verify that the token's signature is correct.

Jochen Bedersdorfer
  • 4,093
  • 24
  • 26