Verifying Logins

I’m trying to figure out how to prevent hacking/impersonation in Buildsim. There is a central user database, but servers are hosted by players. Currently, users login on the website and click a link to join a server, which creates a webstart file with the correct information filled in. The problem is that people can save the web start file locally and edit it–not good! I was orignally going to have the client send some kind of user-specific key to the game server–their password hash, or one generated by the website that is used only for multiplayer. But then I realized that a server admin could steal someone’s key using wireshark and login as them anywhere they wanted.

I guess I need to make the key specific to each server somehow, but how? Using the server name or something as a salt would work, but eventually someone would crack it and leak the details of the hash on /b/. Any suggestions?

You can do a hash handshake. The password will not be transfered.

Google “MD5 handshake” but apply it using another hash function (like SHA2)

You end up with a structure like:
Client -> User Hosted Game Server -> Secure Central User Database

  1. “Client” wants to login
  2. “Client” sends username, sends it to “User Hosted Game Server”
  3. “User Hosted Game Server” sends it to “Secure Central User Database”
  4. “Secure Central User Database” generates salt, calculates [hash of (salt+client.password)] , but sends [salt] to “User Hosted Game Server”
  5. “User Hosted Game Server” sends hash to “Client”
  6. “Client” knows own password (obviously) and calculates [hash of (salt+client.password)], and sends it to “User Hosted Game Server”
  7. “User Hosted Game Server” sends it to “Secure Central User Database”
  8. “Secure Central User Database” compares remembered [hash of (salt+client.password)] with answer from “Client”
  9. “Secure Central User Database” sends SUCCESS/FAILURE to “User Hosted Game Server”
  10. “User Hosted Game Server” now knows whether “Client” is authenticated, disconnects from “Secure Central User Database”
  11. “User Hosted Game Server” sends SUCCESS/FAILURE to “Client”
  12. “User Hosted Game Server” and “Client” do their magic.

This is basically a hash handshake with a proxy in between. The proxy becomes the server once the handshake is finished. Note that “Client” never connects to “Secure Central User Database”.

Note:
The above communication suggests that “Secure Central User Database” has the ‘client.password’ stored in plaintext. This is inherently unsafe, so (once it works) you can replace ‘client.password’ with ‘hash of (hardcoded salt + client.password)’ on both sides of the handshake. Keep in mind that it doesn’t matter that clients know the password-salt used on the server. This renders MD5/SHA lookup tables useless.

Note 2:
The “Client” must guard against the “User Hosted Game Server” sending a hash of “” (empty string). That way the “Client” would hash (password+"") and send that to “User Hosted Game Server”, which can then lookup the hash in a lookup table. A better salt-hash-function than hash(salt+password) would be hash(hash(salt), hash(password)) anyway.