-
-
Notifications
You must be signed in to change notification settings - Fork 21k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add easy encryption to HighLevelMultiplayer Api. #19110
Comments
Maybe that would also be needed for stuff as simple as an online leaderboard? |
Why specifically leaderboards? |
@raymoo I was just giving an example of use case for encryption, since a leaderboard needs some way to prevent hacking results using keys. |
@Zylann I don't know what it means to hack results using keys |
@raymoo sending a hash from the client with scores so that you can check if it's valid server-side by computing the hash again with the same algorithm and a private key. Godot has MD5 only so far though, but maybe it's not related to that issue actually... |
@Zylann Makes sense, for a moment I thought the issue was to add some ssl-like layer under the multiplayer API. |
SLL requires a public registry. I'm sure it's interesting for companies that leads online business, but too complicated to regular users. it's a good point to think about. |
Long story short, there are multiple ways to achieve encryption:
None of them prevents cheaters, nor users to read the content of the data being transferred (but DTLS does protect from eyesdropper, while AES alone doesn't unless you also implement secure key exchange). If you want to avoid cheaters, make the server authoritative (i.e. do not trust any data coming from clients), there is no other way (at least to my knowledge). If you want to protect data from the users, don't send it. If you do, no matter what you do, the users will be able to read it (otherwise the application on their end wouldn't either). Both those options are viable, and PRs are welcome, sadly, I find myself with very little time between work, GSoC, and other personal obligations. |
The first option, to add symmetric encryption APIs, should be done anyway and doesn't have much to do with networking. Something like proposed in PR #17721 but preferably with stronger defaults. You could then encrypt data before sending (or before storing it to a file, or...). Only way around that would be to add DTLS support (or a similar, encrypted transport that does the heavy lifting). Note that there is a GSoC project ongoing for adding WebRTC support; that uses DTLS by default, so should be encrypted. Personally, I'm interested in the first option, to add APIs to encrypt/decrypt data manually, but not much in adding encryption support to the ENet backend. I think thats overkill. So what if somebody reads your position updates? IMO, encrypting specific things like in-game chat is more than enough. The first option would suffice for that, or you could even use HTTPS for that right now, which would probably be enough for chats and similar messages. In the future, you may be able to use WebRTC to get encrypted transfer. |
I think that symmetric key encryption is probably the correct approach here. Any sort of TLS approach is rather heavy handed and has enough overhead that I worry about resulting performance. In regards to symmetric keys, I do request that a wide array of ciphers can be used. N9t only the number of bits, but also things like the chipher mode (e.g. GCM, CBC, etc..) |
@jonbonazza Does your suggestion include some method of key agreement? |
Does not Godot have a method for encrypting data already? |
Actually, I was thinking about it more, and I don't think symmetric key encryption will work for this particular use case after all. On of the beauties of symenc is its simplicity. There is no key negotiation--both ends of the connection simply require the same key in order to enc and dec data. This is great when both the client and server are controlled by the same entity and live within the same datacenter, but for something like a game client this won't work at all and is virtually no better than having no encryption at all. Since the key is the same on both ends of the connection, there's nothing stopping a malicious party from grabbing the key from the client, intercepting the inflight data, decrypting it, modifying it, and renencrypting it before passing it on to server and the server would be none the wiser. This is actually an ideal candidate for asymmetric encyrption. Honestly, Im not too experienced in assymmetric encryption options on top of UDP. TLS is certainly the most common form of assymetric encryption, but requires TCP. DTLS is a derivative of TLS but built for UDP. I have no experience with DTLS though, so I am unaware of its downsides, nor of any alternatives. |
Also, like @Faless mentioned, even TLS doesn't completely solve the cheater issue, but then again, nothing will as once you distribute a client to another, uncontrolled machine, you can't trust anything that comes from it. |
The clients can't know if it's indeed the authoritative server or they're being MITM'ed (to steal passwords etc) or it's a totally fake server (similar for client to client communications), and that's the one of the arguments for having TLS in place. And this is a problem that would need be addressed before worrying about cheating. |
@tagcup the whole purpose for using an authoratative server is so it doesnt matter what the client thinks. The server is the validator and the arbiter. If the client sends something the server doesnt agree with, it ignores it. |
It will matter when your players gets MITM'ed and get all their passwords and other personal information owned and you get sued by some. |
So i think you are missing the point of this issue. Passwords and personal info would never be sent via the high level networking library. For that, you would use an http client or something, which of course should have tls support. This is for in game networking, which if you are at all a competant game developer, you would never send PII or credentials with. |
@jonbonazza I totally agree with your point of view. In some moment the key will need to be negotiated and will can be caught. it is a waste of processing.
Sad, but true.... At this moment I would be content with 2 things:
|
If you're meaning gambling in particular (which, considering some of Godot's sponsors, would be logical) what are the legal requirements for that? I know they can be pretty arduous and probably beyond the scope of this issue (beyond possibly providing a framework). |
@jonbonazza
Would have to be careful with this so that users don't get fake security because they implemented it badly. You would at least need to incorporate a (randomly-initialized) sequence number into the message. It would be ideal if the multiplayer API handled this on its own, because I think it would cover all cases of wanting to encrypt the high level multiplayer API. |
DTLS does protect you from MITM if used correctly. There is no way we can implement secure key exchange out of the box, that's something game devs will have to take care of depending on their requirements and infrastructure (and we should give warning in the doc about it). At the same time, DTLS can be used wrongly, as can SSL (and some devs do actually implement it wrong), but then again, game devs should know what they do. I think both should be implemented:
|
Agreed faless, thats the way to go. :) |
Yes, DTLS (or any asymmetric ebcryption scheme) will protect from MITM, but when the client is on a user's machine nothing will protect the attacker from just grabbing your keys and sending w/e they want or performing outbound MITM that way. This is why most games dont use security at the transport layer already. You're free to use it in your game, of courae, but expect massive slowdowns (and depending on your game, it very well could render it unplayable) and minimal added security. |
DTLS is fairly low-latency. The biggest overhead and increase in latency is in the initial handshake. During runtime, cost should be fine. WebRTC does use DTLS and seems to work for soft real time applications like VOIP, video streaming and games. If you don't want that overhead, well, DTLS is of course going to be optional; you don't need to use encryption. We won't force you. :P |
So, did you guys decided for the features on bellow?
|
@Malkverbena I think thats a good summary. Someone has to actually implement those things though. Contributors welcome :) |
I would love implement it all with my own hands, since these improvements benefits me directly. |
Hello again folks. I'm back! |
@Malkverbena There is an open PR implementing AES encryption methods like you propose, although I'd prefer a stronger mode/config/defaults than it currently implements. (#17721) Best option for networking encryption for us still seems to be looking into DTLS. |
@mhilbrunner What exactly you would like to see on that PR above? |
Hey folks |
I don't know this library. |
Hey folks. |
@Malkverbena |
Using PoolByteArray as input for cryptography can also be userful to network some way? |
We would need to use uint8_t * directly instead for performance, but it's a start.
String uses 1 or 2 bytes per character depending on the UTF8 encoding of the specific character. |
Do you mean Vector<uint8_t> ? Where can I find the documentation of Variant, String and Array? read documentation is faster than read the code... |
Hey! https://github.com/Malkverbena/cripter As I said before, my time is really short and often I have to sacrifice hours of sleep to code. |
I would appreciate some feedback. For now it can encrypt/decrypt bytes and var using CBC and GCM. GCM naturally authentication requires authentication. @Faless I'm not sure if I got what you meant. Anyway I'm using uint8_t. Not the best way yet but it's a experience for now. |
The algorithm ed25519 is also part of tls 1.3 so it may be useful to expose. |
Not to discourage the development of the AES part, but I believe the DTLS portion of this issue is much more useful. If you have just the AES portion, there are many ways someone could try to use it with networking and produce insecure code. The most obvious way is if they just used a fixed key, but even if you negotiate a new key per connection (through some external mechanism), and then communicate with the server by encrypting string arguments with that key, it can allow a MITM to forge bad inputs by replaying older messages sent by the client, since the same message will always have the same output if encrypted by the same key. Depending on the specific game, the attacker may also be able to guess the contents of the messages based on frequency, or by joining the same server and correlating in-game events with messages between the client/server. I think you can make it secure by adding a sequence number to each message, but I'm not sure and I'm not a crypto expert. You would still have to do manual serialization of all the RPC arguments which would be a pain (but probably could be extracted into a convenient library if it had to be). |
@raymoo I agree. For Internet communication, asymmetric cryptography is the best option. However I can think of at least half a dozen uses for symmetric cryptophraphy. It would be very useful at least to be able to encrypt an Raw Array using symmetric encryption. |
What are some of those use cases? I only skimmed quickly through the thread, so sorry if some have already been listed. |
I think this is partially addressed by https://godotengine.org/article/basic-cryptography-ssl-improvements Next step is DTLS, which is WIP and will be available in 4.0: https://godotengine.org/article/dtls-report-1 |
Fixed by #36296. |
I was thinking of some important security features that are lacking in Godot. When you have an online business it is necessary to protect the data of your users and avoid cheating. In the gaming industry it's no different, especially for companies that move amounts of money.
Due to this, I think encryptions methods on network api would be very welcome.
This will not solve all the security issues but it sure is a big step.
These features should also attract more attention to the engine from companies of all sizes and more users to Godot.
My propose is add some encrypt method on the api.
Maybe something like:
host.set_encrypt_mode(key, settings)
get_tree().set_network_peer(host)
And if possible add support to WebSocket Security
The text was updated successfully, but these errors were encountered: