Cheers!
To expand a bit on my answer instead of just throwing in buzzwords (this is pretty much the longer version of my reply, since I have nothing to do while waiting for my OS to restore):

Use TLS for communication. TLS (or SSL, but we don't call it that way because Microsoft didn't want a Netscape invention to be incoperated into Internet Explorer) is a protocol that takes care of authentication and encryption. The server has a certificate that signed by a CA (certificate authority) and optionally one or more intermediate CA that together build the so called chain of trust: The root CA is trusted, ergo all certificates signed by the CA and its intermediate CAs is trusted as well, ergo the certificate that your server presents is trusted ergo the server is who it says it is. Is the chain of trust broken, the server may or may not be who it says it is and the connection should be refused (the huge red pop-up in browser that says the server couldn't be verified).
The certificate that the server presents is used to authenticate the server to the client (it can also work the other way, but that's rarely done outside of enterprise networks). Once the server is verified, a secure connection is established between the client and server that provides two features: It can't be man in the middled, if someone tampers with the packets between client and server, it's detected.

This leaves you with one problem, any server that provides a valid certificate becomes cool. This is okay for web browsers, but not so much for games. This is where certificate pinning comes in. Since you know your server, you also know in advance which certificate to expect, and you accept nothing but that certificate. This also leaves you with the option to self sign the certificate, which previously you couldn't do (since a self signed certificate doesn't have a chain of trust since you are not a trusted CA. If you'd accept any certificate, anyone could've forged it and presented it to your game and it would just accept it).

Bonus points, create a revocateable certificate. Revocation of certificates is an extension, and a rarely used one. It works by checking the certificate, checking if it is revoked (the certificate includes a field that tells you where to check the status of the certificate), and if it is revoked, you tell the server to bugger off. Why? Because certificates can be stolen! They work using public key or assymetric cryptography, basically a form of cryptography that has two key: A private and a public one. The public one can be known by anyone and can only be used to encrypt data, the private key known to you only must be used to decrypt the data. If the private key leaks, see also heartbleed, your certificate is no longer secure and should be revoked.

So, now you have a secure connection to your server. How you talk with it isn't very interesting, but a REST API is always good and easy to use. Provide a simple set of API endpoints to create users and login users and verify sessions. Maybe also logout if that is something you want (but have internal functions to invalidate sessions, eg when a user resets their password, invalidate all sessions the user previously had).

User creation and password verification: Encrypting passwords is bad, because then you just need a key to get the plain text passwords back. What you want is a cryptographic hashing function, a function where you input something and get a value back from which there is no chance to get the input from. Small variations of the input have huge impacts on the output. On top of that, you want to salt your passwords. This is needed to combat rainbow tables, because, hashing the same input results always in the same output, so there are lists of millions of commonly used passwords and their respective hashes for all flavours of hashing functions.
But! You want to use a new and random salt per password! Keep in mind that the salt is not meant as a super duper secret that protects the user. It's meant to protect the rest of the users! If your database with the hashes leak, the salts can and will leak as well. But, that keeps people from using rainbow tables with a single salt (because from a single known salt you can create a known table and just check all paswords againt that). Having a unique salt per passwords requires the attacker to brute force every single password that he/she is interested in. The majority will be save since it's only worth the trouble for some people.

Now, next up, adaptive hashing functions. Something like SHA512 is nice, since it creates really nice hashes without many collisions (eg two inputs resulting in the same hash). But it has a downside: It's fast. Insanely fast and can be parallalized. That's really cool for brute forcing, but you want to keep people from doing just that! The solution are adaptive hashing functions. They are deliberately slow and can't be efficiently implemented in hardware and/or be parallelized. If it takes 100ms to create one hash, it is still fast enough for your server and authenticiation of the user, but it takes a crapload of time to brute force any password.
The faster computers get, the more rounds you can add to your hashing function, and the longer it will take for it to compute. A battle tested and established adaptive hashing function is bcrypt.


Shitlord by trade and passion. Graphics programmer at Laminar Research.
I write blog posts at feresignum.com