I am designing a multi-player game with a single server that handles multiple worlds. Each player logs into the server initially before requesting which world to join.
The server has a fixed IP address that is currently the same as the site's IP address. This may change in future if servers need to be ran in parallel, however as of now it is a safe assumption that the server is, in fact, the server, and not an imposter.
Passwords on my site are hashed using bcrypt and a salt, and stored in a MySQL database.
I do not currently have an SSL certificate, though I am planning to get one ASAP and certainly before any payment details are handled by the site, but the game is still likely to be connecting over an open TCP connection, so my security needs with respect to authenticating game users needs to be handled manually.
The main audience of the game is young teens, but particularly those able to write a little code, so I can expect a small amount of them to be relatively competent programmers and a smaller subset to be able to reverse engineer and break into an insecure system.
My currently considered approach
I spent a while thinking about this issue myself and came up with a solution that appears to be classified under a "Challenge-response" algorithm, that is:
- Client sends username
- Server receives & verifies username, and sends a request for password data along with a unique token. My current idea for this unique token is to generate a random string, MD5 it, then prepend a unique, incrementing integer to ensure both that the same hash is never sent, and that it is not predictable.
- Client receives token, hashes password using bcrypt with the known salt to get the value in the website database, and then appends the token before running it through bcrypt again.
- Client sends back this new hash over the socket
- Server reads this, verifies it, and notifies the client that it is now authenticated as the username they initially sent.
No device but the true client and the server should be able to find out the password, or authenticate by eavesdropping for exchanged sensitive data.
I have a particular issue with this approach in that now the secret salt I have been using on my web-site to hash passwords is going to have to be known by clients. I am struggling to think of a reason this is compromising to my security, but it feels wrong. I suppose, in theory, they can now pre-generate rainbow tables then if they managed to obtain a copy of my database, there would be a much lower amount of time between them obtaining it, and cracking a decent number of user's passwords, meaning that my users accounts are at a larger risk as they will have less warning should anything happen.
Outside of this, though, I also would appreciate greatly an evaluation of my considered approach and any pointers or links that may be helpful to securing it more.
I am more than happy to answer any questions! Thanks!