3

I'm working on a multiplayer game using WebSockets. I've decided all user data will be stored on the client, eliminating the need for authentication using passwords etc.

LocalStorage
'save' -> '{"key":"value", "key2":"value2"}'
'hash' -> '<hash of save>'

The idea is to store the user data in plain text but to also store a hash which can only be calculated by the server (running Node.JS). The client will send both save and hash to the server to be checked and loaded into memory for this session.

Now, my question is:

  • If I use SHA256 to hash all the save data, how can I prevent a user from generating their own hash for the data?
  • Then, (assuming the answer to part 1 is 'salt',) will using salt keep me safe or can this be calculated? (I can make the salt partly different for each user)
  • Will the client change the local 'save' ? – Yorick de Wid Sep 2 '16 at 20:33
  • This doesn't eliminate cheating. People may share their save files with each other, complete with valid hash (or HMAC). To prevent cheating you must store the save data on the server. – Michael Hampton Sep 2 '16 at 21:59
4

What you want is something that ensures integrity of your data.

The most common solution for this is to use an HMAC, that is a keyed digest. NodeJS has an API that calculates HMACs. Compared to a "salted" hash, where you would keep the salt private, HMACs are designed to be secure even against some additional attacks, such as length extension attacks.

As long as you keep the key private (and large enough), you should be able to use the same key for all users.

Be aware that this won't prevent people from sending you a previous version of the data. All this does is guarantee that the data was valid at some point. If you want to be sure they're sending you the latest version, you would need some server side storage to store either a version number, a timestamp or the last data digest. If you choose to store the last digest, a normal hash will suffice, you won't need to send the hash or a HMAC to the client.

  • Thanks, that's a good idea! I think I might need to consider storing the hash on the server side, as you suggest. – Peter Gordon Sep 3 '16 at 10:28
1

No, salt (in classical sense - value known both to server and client) won't help.

When generating hash, server should encrypt it using a secret known only to itself (and never any client), and on reciveing it decrypt it and then check.

But I guess by salt you probably meant prepending some (hopefully resonably big) amount of server-only secret data to save data, and then doing SHA3 (or HMAC) on that result. Yes, that would be secure enough too. (But make sure the secret is reasonably big so user can't bruteforce it; better yet prepend one big secret and append another big secret for more resilience).

As mentioned by @AgentME in the comments, beware of hashing alghorithm used due to some of them being suspectable to Length extension attack

  • 1
    Use HMAC instead of just a basic hashing function (plain sha256), or else you can be susceptible to length extension attacks. – Macil Sep 2 '16 at 20:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.