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
- “Client” wants to login
- “Client” sends username, sends it to “User Hosted Game Server”
- “User Hosted Game Server” sends it to “Secure Central User Database”
- “Secure Central User Database” generates salt, calculates [hash of (salt+client.password)] , but sends [salt] to “User Hosted Game Server”
- “User Hosted Game Server” sends hash to “Client”
- “Client” knows own password (obviously) and calculates [hash of (salt+client.password)], and sends it to “User Hosted Game Server”
- “User Hosted Game Server” sends it to “Secure Central User Database”
- “Secure Central User Database” compares remembered [hash of (salt+client.password)] with answer from “Client”
- “Secure Central User Database” sends SUCCESS/FAILURE to “User Hosted Game Server”
- “User Hosted Game Server” now knows whether “Client” is authenticated, disconnects from “Secure Central User Database”
- “User Hosted Game Server” sends SUCCESS/FAILURE to “Client”
- “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.