Closed RandyGaul closed 5 years ago
I had personally assumed that one of the use cases for having redundant server addresses in the secret client data was so that a game server could verify if a client was allowed to connect to that server, without needing to access some sort of central "sessions" database.
@stellarLuminant Right, that makes total sense. I guess a better question would have been "why not make the connect token secret section a lot smaller", since that seems to remove redundancy, simplify things quite a bit, all without sacrificing any security.
Also, I edited my OP a lot -- my apologies! You probably responded to an old version (just fyi in case you had insights to any new questions I wrote).
The public token data is unencrypted, because it’s stuff the client needs to connect to the server, eg. The server IP address, private keys, timeout whatever. It’s not encrypted by anything, because the token is sent down from backend to client via a secure channel, typically HTTPS.
The internal part of the token, the private stuff that you think is redundant, is encrypted by a key that the client does not have (by design). The client passes this opaque blob over an unsecure channel (UDP packets) to connect to the server.
The server uses this data to verify that yes, in fact this client is authorized by the backend and is allowed to connect to the server.
That is all. There is no redundancy. You are trying to optimize something you don’t understand. Read the spec again, and understand why the client cannot read, modify or generate the private token data, and why this is necessary for security, then you’ll see why no redundancy exists.
Cheers
Thanks for the response Glenn! I appreciate you helping me to learn about your design.
There’s one thing I’m confused about. Does the typical use-case have the connect token share the same IP address list in both the private and public sections?
If so, is there an error in my proposal? I know you’re busy, and the nature of the question is complicated. You’re right, it’s an attempted optimization. This is typically how I personally learn. I understand it’s a long question though, and I apologize for not being able to shorten it any further. So feel free to ignore if you prefer :)
OK so I just figured out the problem. Not encrypting server IPs lets packet sniffers attempt to steal tokens before they are used, by knowing which server the token can be used to connect with. Which actually leads to a new question... I'll open a different issue.
Edit: Nope sniffing isn't possible: https://github.com/networkprotocol/netcode.io/issues/84. So it still looks like the server list in particular does not need to be secret, so my original proposal still looks ok. All that's needed is for public info to be covered in the HMAC with the Additional Data part of the AEAD.
After thinking about all this some more, I do think the netcode approach is also quite simple, since just encrypting the entire token and duplicating the server list is very straightforward to understand once the design intent is understood. As far as I can see: both approaches should be pretty much equivalent with negligible differences.
Hi there, I was studying the connect token design and have a couple questions. I am just trying to learn about design intentions and use-cases.
The connection request packet is defined as the connect token minus the REST SECTION. The PUBLIC SECTION of the connection request packet can be used as the additional data in AEAD. This way the connection request packet is entirely protected from tampering, and the client id/userdata/keys are still encrypted. I imagine there is no security risk, since unencrypted information is publicly knowable to authenticated clients anyways.
This design might have some benefits:
Does this consolidation/simplification make any sense? I'm probably missing some obvious problems, and am asking to better understand the netcode design.
P.S. I moved the SECRET SECTION to the end of the packet. This way the SECRET SECTION resides at a known byte-offset, and the server can quickly validate connect tokens, just as before, without the need to parse the server address list.