- Client connects to game server and transmits the auth ticket. Doesn't this already need to be encrypted to prevent against sniffing on open networks? But the server apparently doesn't retrieve the encryption key till later, so what is stopping someone else grabbing the ticket and connecting as you?
- Is there any reason not to start the sequence numbers at 0 given we already using a random encryption key?
- Aren't sequence numbers going to be fairly useless with UDP unreliable messages?
- What is a suitable hash for ongoing messages once authentication has been established? I assume this is really just a checksum to make sure the data hasn't been tempered with.
Also, would you still give the same advice today? Reading the archives here I get the feeling should really be looking at TCP/TLS instead, if at all possible...
1. Unless the player is playing the game on an open WiFi network, it is actually pretty hard to "tap into" the network connection and sniff the ticket. So, the question is whether your attack vector includes those with physical access to the networking infrastructure. If the ticket is tied to a remote IP address, then even stealing the ticket is not good enough unless you can also steal the IP address. It turns out that modern day use cases like the open WiFi on Starbucks and McDonald's and similar places allow you to do both, though (like Firesheep,) so using transport-level encryption is advisable if you want to protect against that.
2. If you have some other way to detect replay attacks or blind data injection, then the sequence number can start at 0 every time.
3. Sequence numbers are highly useful for UDP, because they let you know which of your packets make it through, and which ones don't.
4. If the goal of the "hash" is to protect against network-level hardware corruption, a crc32 would be fine. If the goal is to protect against a determined attacker with the capability of acting as a man-in-the-middle, then a HMAC with a shared secret and a strong algorithm is needed. A straight hash with a shared secret is not good enough, because the attacker can use hash data extension to inject his own data at the end of the message. HMAC fixes this. Btw; using md5 for the HMAC algorithm would let someone inject data as well, because creating 16 bytes at the end of a packet that achieves the HMAC you want with MD5 is no longer a computationally hard problem. I'd suggest sha-1 for now, for games, although if you're all security-minded, by all means use sha-256. And hope the NSA isn't interested in cheating in your game :-)
If you're using TCP, then TLS is a fine transport mechanism, but it does not solve the authentication problem by itself.
If you're prepared to set up unique client certificates for each client, you can do that, though. if you want to go that route, that would be a perfectly fine alternative, as far as I know. (I e: it's likely that self-signed self-issued certificates from an audited code base will be secure; it's also likely that pay-for CAs are by now not considered 100% secure.)
IIRC, you also can't really use UDP with the TLS stack as it uses full-stream in-order CBC.
All of which goes to the question: What kind of attacks are you *really* trying to defend against? If your game is a valuable target, it's much easier to install malware on your players' computer, than it is to do a cryptographic attack.