Generating a secure cookie token to store persistently

可紊 提交于 2019-12-05 04:46:25

问题


I am trying to create a login and register page for my website. I am looking to use cookies in order to track a users session however I'm trying to implement it in the most proper and secure way. I've tried looking at tutorials and forums but most of them are outdated and use techniques that people comment are not secure. I understand tokens needs to be randomly generated and encrypted so I found one response that suggested to use a MessageDigest on UUID. But I found more articles suggesting that this may not be as secure as I think... Any suggestions on a secure way to generate cookie tokens to store in my db?

When I tried using the UUID method I got stuck on how to place it into my db since I'm having trouble finding how to turn it into a string. Here is my code...

UUID uuid = UUID.randomUUID();
MessageDigest salt = MessageDigest.getInstance("SHA-256");
salt.update(uuid.toString().getBytes("UTF-8"));

回答1:


Your current method is, well, rather terrible. Consider if I, an attacker, learnt that my victims UUID is some value x. I could then simply take the SHA-256 hash of x and store this as a cookie on your website. Tada. I'm now impersonating my victim.

In saying that, a very secure way to produce tokens for login systems is something relatively similar. Consider the following JSON object:

{ "expiry": "1:30:00 24/10/2012", "userID": "F68D4A77DC34" }

If we stored this JSON object as a cookie on the client-side, it would be an excellent way to determine who our user is and when this object expires and the user needs to login again.

But wait, this won't work, because anyone could change the user ID or the expiry and your server won't know!

We can solve this easily by introducing an HMAC. An HMAC is a Hashed Message Authentication Code. We first generate (once, ever) a random HMAC key, k, to use on the server. This key should remain on the server and never be transmitted.

When a user logs in, we create a JSON object similar to the one above and then feed it through an HMAC (say, HMAC-SHA256) with k as the key, and then append the result of this to the JSON object as base64 encoded bytes. It sometimes helps to use a splitting character too, say ".".

We then end up with the following:

{ "expiry": "1:30:00 24/10/2012", "userID": "F68D4A77DC34" }.ScvlfpUDqgxtDPH4jsK44d+4cMNG+5yCvASJkVEI11o

This token would be fine to use exactly like that, but some people like to base64 encode the JSON too. We end up with something like this in that case:

eyAiZXhwaXJ5IjogIjE6MzA6MDAgMjQvMTAvMjAxMiIsICJ1c2VySUQiOiAiRjY4RDRBNzdEQzM0IiB9.ScvlfpUDqgxtDPH4jsK44d+4cMNG+5yCvASJkVEI11o

It is easy for us to verify that this token is legitimate by taking the JSON object, performing the same operation again, and then comparing the result of the HMAC with the one that is attached to the token. If they match, we know that our server generated the token and that it is legitimate.




回答2:


There appears to be some misconceptions about what this "secure" token actually means.

It can be anything, in theory. You could use a username, or an incremental id counter, or salted hash of the username, or a uuid.

The question is what are you using it for and why?

If you're using it because you just want information on how long requests are taking, a number works just fine (in theory; not saying I recommend it, more on that later). You don't lose anything major if someone fakes the id number and why would they? They don't see an actual benefit from it.

If you're using this token because it determines who a user is for permissions purposes, then obviously your goal is to make it so it can't be faked. If you want it to be faked, then you should make it truly random and unique. So you could, quite easily, just use UUID.randomUUID().toString() - This is highly unlikely to be spoofable as someone would need to know the exact nano-second precision on your machine as well as the ability to know what the state of the random number generator for the other bits of the uuid are. And that simply won't happen.



来源:https://stackoverflow.com/questions/45971800/generating-a-secure-cookie-token-to-store-persistently

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!