I am working on a round based web game where only one client/player at a time can perform an action. Throughout the game every player will have a websocket connection to the server. The client will send simple JSON messages like
My requirements are these.
- Nobody (player,attacker,man-in-the-middle) must be able to fake another players actions.
- Ideally it works without the users username/password.
- Ideally it works for unregistered users.
Some Ideas I had so far.
Method 1: Let the server send a hard to guess hash only to the authorized player and let the client send it back in the message like this
So if the server gets a message with the correct hash it must have been an action from the authorized player. A new hash will be computed for every message.
Method 2: I thought method 1 will be not secure enough. There is still a chance another player might guess the hash. So I thought I could implement it this way
At game start server and client will agree on a secure key (like in Diffie-Hellman key exchange)
Server creates hash and encrypts it using for example AES and the key and will send it only to the authorized client.
Authorized client will decrypt the hash, add the action, encrypt the JSON message and send to server.
Server will decrypt the message and check the hash with the original hash it send.
Although I am not sure if method 2 is actually more secure than method 1 and will prevent wild guessing. Plus I will feel uncomfortable implementing a method to securely exchange keys.
Method 3: Ignore all of that and let the server track the authorized websocket connection. The server will then track the websocket connection of the currently authorized player and ignore messages from all other connections. Is this safe against man in the middle attacks or other attacks? Is it guaranteed that the websocket connection is not hijacked? How would I protect against that?
What method is most secure? Is there another method I should consider? Is this safe against man in the middle attacks or other attacks?