🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Login System

Started by
11 comments, last by hplus0603 8 years, 11 months ago

So i'm trying to follow these steps:

1. Client sends username to server.

2. Server sends a random number to client.

3. Client encrpyts the random number with password hash as key.

4. Server encrypts the random number with correct password hash from database and checks if the two of them match.

So as far as i understood i have to store both hash and salt in database in order to check if they match. But how will client know which salt to use ? Wouldn't hash be different if a different salt is used ? Do i have to send salt via socket then create hash ?

Advertisement
In the algorithm you suggest, the "password hash" is the same thing as the "password" -- if someone manages to read your password database, they can impersonate the client, without further decryption.

The method you suggest can be secure against snoopers on the network and impostors, assuming that you use a cryptographically strong challenge and hash/digest algorithm. However, it's not that great as a defense against social engineering, or server-side exposure.
It turns out that, for games, social engineering is the biggest problem, and server-side exposure is the second-biggest. Snoopers in the middle aren't really a credible attack vector, because the dollar value of an individual account is low. (Although it's still useful to protect against.)

I would recommend that you use an available SSL/TLS library to make the user log in. The user should provide its password in plaintext. You should salt and hash on the server (say, using scrypt() or bcrypt()) and compare to the database-stored value.

If you then need to actually talk to the server using UDP, you can do something like the following:
1) Issue a ticket from the server (a random number) and remember the ticket issued to the client
2) The client formulates its packets as:
(clientid encrypted-with-ticket(32-random-bytes data)) hmac(entire-packet, ticket)
3) The server then verifies each incoming packet as:
- lookup ticket for client
- verify hmac -- if fail, stop here
- decrypt and use the data

The 32 random bytes are there because you don't have a shared IV between client and server, so instead you generate a new random number each time, to avoid chosen-plaintext attacks, but you have to include it in what's encrypted for that to work.

Servers would presumably use the same mechanism to send data to clients.

If you, for some reason, cannot use TLS for the original login and ticket issue, then you're in for a bit more hurt. Or perhaps you can punt on any strong security for your game, and focus on making it a great game, first, and come back to security when it's clear that the game has enough players that it needs it?
enum Bool { True, False, FileNotFound };

Thanks for your answer. So i should store salt/password_hash in database and send password as plaintext to server then create/compare hashes right ? But if someone somehow is abled to monitor the socket wouldn't he be able to obtain the password if the authentication is successful ?

Thanks for your answer. So i should store salt/password_hash in database and send password as plaintext to server then create/compare hashes right ? But if someone somehow is abled to monitor the socket wouldn't he be able to obtain the password if the authentication is successful ?


That is correct. With proper use of SSH / TLS, it's less likely that someone can monitor the socket, then that someone can get a dump of your user database. Also, if someone sniffs a particular connection, they only get that one password, not every password for your system.
And, finally, it's much more likely someone will put malware on your user's machines and install a key sniffer; there's really no good defense against that other than two-factor authentication.
enum Bool { True, False, FileNotFound };
I don't get ssl socket. It has a certificate with a private key and a public key. Are these 2 key used only for connection or for both connecting and data hashing. But then the hacker has the certificate can't they just crack the 2 keys any way.
And the cert has a time limit you would need to send a new certificate to all clients. Hard for managing.
Hopefully the hacker won't get ahold of your secret key/certificate. If they do, they can impostor you and/or decrypt captured traffic.
If you make your own certificates, you can make them last for 10 years and worry about whether to update them later.
SSL/TLS certificates seem to work well enough for all of the HTTPS sites on the web, though -- anything from secure email to google.com to your bank is using it. And, if you use your own TLS/client (rather than a web browser,) you can ship your own trusted signing key, so you can use your own signing key, not paying for a public certificate.
enum Bool { True, False, FileNotFound };

@hplus0603 Are there any OpenSSL tutorials for socket securing that you could recommend ?

Hi. heres a good read on password hashing. And OpenSSL Im at the same stage, and have been reading stuff for the last week. I have some other links on my other system next time I log in Ill post them, it shows how to create the certificate used in the hand shake when clients connect using a SSL socket wait may be a boost one sorry.

@ankhd Any useful reference would be appriciated. In addition to that, have you come across to any c/c++ bcrypt library while reading about password hashing? Thanks.

Are there any OpenSSL tutorials for socket securing that you could recommend ?


I know of no good ones. Especially the OpenSSL library is a lot harder to work with than needed. If you can stomach GNU license, then GnuTLS may be better... There's also Mozilla NSS, which has the somewhat-better Mozilla license.
WikiPedia gives you threads to pull on and see what comes loose.

any c/c++ bcrypt library


It turns out that bcrypt was first released as a C library, called, surprisingly, libbcrypt :-) Although unfortunately it lives on SourceForge, which currently has an outage.

If you have your choice of library, though, I'd go with scrypt: TarSnap has the canonical scrypt page.
enum Bool { True, False, FileNotFound };

This topic is closed to new replies.

Advertisement