Information Security Stack Exchange is a question and answer site for information security professionals. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I am writing a multiplayer game. I have a central server which processes everything. For data exchange I use HTTPS protocol. Because this is a game I cannot use computationally expensive systems like RSA for data transfer.

To login,

  1. Client uses sha512 to produce hexadecimal hash from password and random seed.
  2. Client sends "login" request with username, hash and seed to the server.
  3. Server checks if user has not attempted too many login requests and checks whether the password hash matches the hash made from the password in the database. If it does, it sends an access_key and a response that login was successful

To send requests which require login,

  1. Client sends a hash generated from the access_key and seed along with the request data.
  2. Server checks whether the IP has not changed and whether the hash made from access_key and seed is correct. If it is, new access_key is generated from the old one, request data is processed and the server returns the new access_key along with the response from the request.

At any time, if client's IP changes or invalid access_key is sent, the session is automatically terminated.

How secure is this approach? What can I do to improve it?

share|improve this question
8  
I have this general rule (which I think is pretty standard) that if anyone has direct access to the executable version of your software just assume they have your sourcecode for that application. In this case, because you hash your password on the client I would assume any attacker will know the algorithm you use, the method of generating seed/salt (I feel like you mean salt when you say seed but I could be wrong). None of this is necessarily a bad thing however if you have any flaws in implementation an attacker will know about it as opposed to hiding it a little better on the server. – iismathwizard Jan 5 at 15:48
1  
Not that I'm advocating security through obfuscation but it doesn't hurt to reduce the knowledge the attacker has :p – iismathwizard Jan 5 at 15:49
18  
I'm a bit confused as to why a game would need a secure data exchange system that goes beyond that used in e-commerce and banking applications (which just sends username and password to the site over HTTPS, then uses session tokens or two-factor authentication for the extra security layer). Have a proper security certificate, use HTTPS for sending username and password at first, move on with your game. And the IP thing won't help you much, they can change at any time: stackoverflow.com/questions/7550798/… – BrianDHall Jan 5 at 17:00
2  
@BrianDHall: There can be legitimate reasons to spend effort on game security. Games may not usually be high-value targets (although some can be), but they're definitely popular targets for attacks. – Ilmari Karonen Jan 5 at 22:58
1  
if client's IP changes Don't do that, you game cannot be reliable played at schools/other large places and at homes where a ipv6 connection is in use connection – Ferrybig Jan 6 at 14:18
up vote 28 down vote accepted

First of, crypto is hard, and you shouldn't create your own.

Vulnerabilities

Your login seems to suffer from a pass the hash vulnerability. An attacker doesn't need to crack the hash to login, they can just pass the hash, and will be logged in. This defeats the purpose of hashing the password in the first place.

sha512 is not recommended for storing passwords, as it's way too fast. Use something like bcrypt instead.

HTTPS and Encryption

You say that RSA is too expensive. But generally, RSA is only used to exchange a key, which is then used with a much less expensive private key cryptosystem.

As you clarified that you do use HTTPS, it should be noted that you do already use RSA. HTTPS uses RSA or diffie hellman for key exchange and some block or stream cipher for the actual data encryption.

As you use HTTPS, you already have data confidentiality and integrity (and server authentication and optionally client authentication), there is no need for additional encryption on the application level.

Advantages of your scheme?

Your scheme doesn't really seem to serve any purpose. You already are secure from eavesdropping and data tampering via HTTPS (and your scheme wouldn't have prevented it anyways).

So your scheme doesn't seem to be about data exchange so much, as it is about authentication.

Generally, authentication is handled like this:

Login:

  • Client sends username and password (plain)
  • Server hashes password, and compares hash against hash in db
  • Server sends session id back

Other Requests:

  • Client sends session id
  • Server validates session id
  • (optional) when session state changes, server regenerates session id

Your approach is similar, but did introduce the pass the hash vulnerability, and contains a seed, which seems to be unnecessary and thus only complicates the scheme. It also regenerates the session id on each request, which isn't really needed and only seems to cause unnecessary overhead.

share|improve this answer
    
I use HTTPS for all data exchange – Mirac7 Jan 5 at 16:04
11  
@Mirac7 That's good. That only leaves the pass-the-hash attack, and the weak hashing (both of which are serious issues). But what exactly are you then trying to achieve with your scheme? You already have confidentiality and integrity (and server authentication and optionally client authentication). Why not go with the normal approach here? (login: client sends user+password, server checks and sends session id; other requests: client sends session id, server checks; when session state changes, regenerate session id) Whatever language or framework you use, it should already support this. – tim Jan 5 at 16:12
1  
@iismathwizard exactly, the password should be hashed server-side and then compared to a stored hash. That way, an attacker that did get access to the database cannot log in with the stored password (except if they manage to crack the hashes). – tim Jan 5 at 17:55
1  
Hashing the password clientside protects the password from the server. So even if someone gets to sniff traffic where TLS is added and removed it's harder to use the sniffed passwords in other places (as password reusing is quite common). Of course server-side hashing is still important. – Gustavo Rodrigues Jan 6 at 12:56
1  
@GustavoRodrigues that's a good point. Of course, using sha512 defeats that purpose as well, and removing ssl doesn't sound like a great idea, but it sounds like a good approach as defense in depth, and does help in case the server is compromised and the attacker logs the traffic in the hopes of getting plaintext passwords. So what you would do is: client: sends hashed password; server: hashes hashed password and compares it to stored hash of hashed password? Sounds like a good idea. – tim Jan 6 at 13:02

... Client sends "login" request with username, hash and seed to the server.

Since the seed is created by the client, the combination of seed and hash effectively form a password equivalent which can be replayed again and again. You are probably trying to implement something similar to Digest Authentication here. But with digest authentication the nonce (i.e. your "seed") is determined by the server and not by the client and thus safe against replay attacks.

Apart from that: you are already using HTTPS which protects the traffic against sniffing and modification. Why build another security mechanism on top of it? Digest authentication is usually used for connections which are not encrypted and has the problem that you need to have the password in clear (or equivalent) at the server. If the connection is already protected against sniffing you don't need extra protection for the password and can send it in clear. This has the advantage that you can store the password then as an irreversible hash at the server.

share|improve this answer
    
So should I remove this entire procedure and I can assume that no attacks are likely to be successful? – Mirac7 Jan 5 at 16:05
7  
@Mirac7: If you use https properly then you don't have to worry about sniffing and thus don't need to protect the data you transfer additionally – Steffen Ullrich Jan 5 at 16:24
    
@Mirac7 In case it isn't obvious, the same principle of "password equivalence" applies to the hashed session key you're generating. There's not much point in changing the key after every single request if you trust your implementation of SSL. Changing the key after every request is going to have a scalability cost as well, and it adds complexity to the protocol with no clear benefit. – Steve Sether Jan 5 at 16:46
    
@SteffenUllrich What does properly actually entail? – Mirac7 Jan 5 at 17:20
2  
@Mirac7: Don't disable validation of certificate and hostname and better use certificate pinning. Alternatively expect a single fixed certificate from the server (which can also be self-signed). – Steffen Ullrich Jan 5 at 17:25

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.