Which server technology to use?

Started by
12 comments, last by nunz 15 years, 4 months ago
I am making a game in flash that is essentially a turn based game. It doesn't need much database interaction, it needs to communicate with the server only every 30 seconds or so. I had originally planned on having it communicate with the database using php and passing variables in the url like http://server.com/login.php?user=bob&password=abc123. Now I am contemplating writing the server as a standalone program. I know it would be more work, but would it be worth it? On that note, how would it interact with the database? Do you have the database in memory and then just actually write any updates to the actual database server every minute or so?
Advertisement
The nice thing with using HTTP (such as a PHP server) is that it's easy to find web hosting plans that can run your server, and your code will work through most firewall and proxy set-ups. If you use some other protocol (such as your own server), then the available hosting plans will be severely limited. Basically, you have to use a virtual hosting program like Amazon ECC, or a self-managed dedicated server, both of which are significantly more expensive than a "regular" web hosting plan at a reputable host like dreamhost.com.

If you choose to go your own server route, then you might not need to use a memory cache, because the back-end database server already caches reads and writes for you (something like PostgreSQL or MySQL). At one transaction per player per 30 seconds, I would expect you to support at least 300 simultaneous online players on a simple shared virtual plan (like the cheapest Amazon ECC offering) with no problems. After that, you can start considering what to do to scale up, which might be as simple as paying more for a faster machine, rather than changing the code.
enum Bool { True, False, FileNotFound };
Whatever you do, please don't put username & passwords inside a query string. You should be able to POST data like that...
FTA, my 2D futuristic action MMORPG
You don't have to put passwords anywhere but on the client. Assuming that the server knows the cleartext of the password, then you can do the following:

1) Server keeps a mapping from "current time" to "challenge." Typically the challenge is a hash of the concatenation of the current time and a server-secret nonce. Sometimes, this is also salted with the user name. For extra security, include the client IP address (but not port) in the challenge.

2) Client requests login credentials for a given name. Server replies with the current challenge, and time used to generate that challenge.

3) Client now computes hash(name, password, challenge) and makes a new request, with name, time and computed hash.

4) The server uses the provided time and name to re-construct the challenge (after verifying that the time is reasonably recent, to avoid playback attacks). It then re-computes hash(name, password, challenge) and verifies that it's the same as that provided by the client.

5) If the hash matches, then the server can be sure that user has provided the right password to the client, but the password was never transmitted over the wire (encrypted or not).
enum Bool { True, False, FileNotFound };
Quote:Original post by hplus0603
You don't have to put passwords anywhere but on the client. Assuming that the server knows the cleartext of the password, then you can do the following:

1) Server keeps a mapping from "current time" to "challenge." Typically the challenge is a hash of the concatenation of the current time and a server-secret nonce. Sometimes, this is also salted with the user name. For extra security, include the client IP address (but not port) in the challenge.

2) Client requests login credentials for a given name. Server replies with the current challenge, and time used to generate that challenge.

3) Client now computes hash(name, password, challenge) and makes a new request, with name, time and computed hash.

4) The server uses the provided time and name to re-construct the challenge (after verifying that the time is reasonably recent, to avoid playback attacks). It then re-computes hash(name, password, challenge) and verifies that it's the same as that provided by the client.

5) If the hash matches, then the server can be sure that user has provided the right password to the client, but the password was never transmitted over the wire (encrypted or not).


Do I understand this correctly?

1) Client wants to login to username Bob with password abc123. Client sends username to server.
2) In database, server stores an entry with the current time as the key, and the challenge is hash(currenttime() . $username . $password . getConnectingIP()).
3) Server replies with the time it just used to generate the challenge, and the challenge we just hashed.
4) Client generates hash($username . $password . $challenge) and sends a request with the hash, username, and the initial time that the request was sent (right? Not the current time?)
5) The server then takes the challenge sent by the client, and after verifying that the current time is within a minute or so of the initial request, it regenerates a hash based on the username, password, and the challenge it generates. If the client and server match, success.

Let me know if I misunderstood something.
No, that's not quite right. The server needs to store nothing in the database per connection. The server has a secret password (call it "serversecret").

The server first does:

$time = currenttime();$challenge = hash($time . $serversecret . $connectingIp . $in_userName);$sentData = array("challenge" => $challenge, "time" => $time);


The client then responds by calculating:

$response = hash($in_challenge . $password);$sentData = array("response" => $response, "username" => $userName, "time" => $in_time);


The server then verifies that the client provided proper credentials by calculating:

if ($in_time < currenttime() - 30) { too_old_request(); }$challenge = hash($time . $serversecret . $connectingIp . $in_userName);$password = read_password_from_database_for_user($in_userName);$result = hash($challenge . $password);if ($result != $in_response) { wrong_password(); }


enum Bool { True, False, FileNotFound };
At the risk of sounding naive, what is the advantage of using the time and ip?

* Assuming the database does not save pure text passwords but a hash.

1) The server creates a small challenge buffer of pseudo random characters and sends that to the client as a challenge.

2) The client creates a hash of the password hash and the challenge buffer then sends that new hash to the server with the username.

3) The server uses the username to look up the correct password hash in the database. Using the password hash from the database. The server calculates the hash of the password hash and the challenge that it sent earlier.

4) Assuming a correct password on the client side the server's new hash should match that of the client's transmitted hash.

The password was never sent over the internet and assuming a quality modern hash function both of these algorithms should be nearly impossible to extract the password from. Although I don't know of every possible attack that can be done.



Edit: I may have just figured out my own question. The algorithm I wrote above does not work with a stateless HTTP connection. The time guarantees the challenge was responded to within a reasonable time frame and requires nothing to be stored on the server for un-authenticated clients.

I guess this could be used for UDP connections as well to authenticate clients without the need to create any server side data about the connection until after the client has been authenticated.

[Edited by - Wolfdog on November 21, 2008 7:47:16 PM]
You're right; the time stamp guards against replay attacks, and the IP guards against impostoring/hi-jacking to some extent.

If the client signs the hash of the password, and the server stores the hash of the password, then the HASH of the password becomes the new password -- you don't need to know the password, just the hash of it, to authenticate. Hence, with this mechanism, the server needs to store something in clear text.

The alternative is to create an encrypted, authenticated channel using public key cryptography and certificates, and then let the client send the password to the server, where the server can hash the password and compare to a hash in the database. This is what SSL does. However, this requires an exchange of trusted public keys ahead of time (such as certificates), and, more importantly, the server still sees the plaintext password at the point of authentication, so the security gains over storing the plaintext password are slim; the attack surface to an intruder or malignant operator is similar.
enum Bool { True, False, FileNotFound };
While I do appreciate all of the login system information, and I will use it, I still don't really have an answer to my initial question: should I run this using php or should I create a server?
Quote:Original post by Ryan Lepidi
I still don't really have an answer to my initial question:


You have the answer, but choice wasn't made for you.

Given the amount of work with actual logic and all other details, unless you have a business plan, funding and deadlines, as well as some help, it's not worth worrying too much about the future.

Use PHP (LAMP/WAMP package) and you'll have the networking and database part taken care of in under one hour.

Can you accomplish the same using sockets and mysql C api? I think the final choice is somewhat obvious.

However, if you do have the above things, then simply decide which approach fits your plan, funding and resources better.

This topic is closed to new replies.

Advertisement