This might seem like a basic question but I have searched around on the forums and couldn’t find an answer that I liked. The issue is that I want to have a secure login method for my game client that runs on smartphones. The app will connect to an authoritative amazon server that will be the main game server for my multiplayer game. I am currently not using Unity’s NetworkManager because I don’t like it much. I am using NetworkServer and NetworkClient to send messages back and forth between client to server. However, the issue is that I don’t think any of this message passing between client and server is encrypted. I believe it would be easy for someone to intercept those messages and read their data. My question is what’s the easiest way to achieve secure communication between client and server in unity? I read something about Network.InitializeSecurity() not being supported anymore in the new UNET. Also my game is not using https or a web protocol, its using C# tcp sockets for everything. I don’t know if I should use RSA keys to encrypt the messages?
Do a diffiehellman key exchange (Preferably EC), make the server also include a signature of his public part of the key exchange with a private RSA key. Make the server verify the sginature with the servers public RSA key, if it doesnt match. Someone is MITM attacking, otherwise. Use PBKDF2 to derive keys for AES. Then you can just encrypt your messages with AES. That’s what the MLAPI does.
Only thing that really sucks is that the ECDiffieHellman & ECDiffieHellmanCng classes aren’t implemented in the Mono version Unity uses. We had to make our own implementation. The BigInteger lib from System.Numerics is not supported either on .NET 3.5
Technically correct, but practically you would never ever code something like this yourself.
I would strongly suggest using some kind of library that does all that is mentioned here.
For example HTTPS/TLS does exactly this.
There are other protocols that you can use that already do those things as well.
The farthest I would go is using NaCl directly, but even that is already slightly dodgy (unless you have experience and know what you’re doing).
But of course it all depends on what kind of security you really actually need.
Keep in mind that there is no way at all to prevent the user/player of your application/game from reading or even modifying the connection (because they have access to the computer), encryption only helps against other attacks (MITM).
No reason not to implement it yourself if you have reference material IMO.
But I would not go for a totally separate protocol, (TCP - HTTPS)
Anyways. Here is the MLAPI’s implementation of ECDiffieHellman. Note that it’s licenced under MLAPI’s MIT licence.
https://github.com/TwoTenPvP/MLAPI/blob/master/MLAPI/NetworkingManagerComponents/DiffieHellman.cs
https://github.com/TwoTenPvP/MLAPI/blob/master/MLAPI/NetworkingManagerComponents/EllipticCurve.cs
If I wanted to use Unity’s WWW class to authenticate the user when logging in how would I do that? Can I use the WWW class to connect to my server’s ip address? Also @TwoTen your github links are not working.
What do you guys think about using Google’s Firebase to handle user login?
https://github.com/TwoTenPvP/MLAPI/blob/master/MLAPI/NetworkingManagerComponents/Cryptography/EllipticCurve.cs
https://github.com/TwoTenPvP/MLAPI/blob/master/MLAPI/NetworkingManagerComponents/Cryptography/DiffieHellman.cs
Lol. Just moved them in a commit
Good for mobile. Idk about games. For games i’d probably go for something like Playfab over Firebase.
@dadude123 do you recommend any https libraries that are unity compatible? Is this something that could work: WebClient Class (System.Net) | Microsoft Learn
So guys what we talked about made me think the answer to my problem was using websockets and using ssl to secure the connection, essentially this is https I think. But even though c# has the .net library for tcplistener and tcpclient when I try to use them with a self generated x509 certificate which is required for ssl the ssl handshake fails and no secure connection is made. After a lot of annoying research it seems that the version of mono that ships with unity doesn’t support ssl out of the box due to various issues related to no trust anchors being installed on mono by default.
So I think the alternate solution that I am probably going to use is gamesparks to handle user authentication and in app purchases. However the actual match data like realtime player position in the map will be sent to the server over a separate unencrypted tcp socket. So I think this solution would keep sensitive user data safe like passwords and in app purchases but not prevent cheating in the game. I think im ok with that as long as users passwords are safe. Is my conclusion logically sound?
If you’re looking for something easy and basic, you can just use XOR obfuscation. It is about the weakest encryption available, but is the easiest to set up and should still deter casual packet sniffing. Someone more determined that knows what they are doing would be able to crack it though.
We are working in .NET, AES is just as easy (if not easier) and MUCH safer.
The problem here is really the key exchange. The diffiehellman classes are not implemented in Mono. So you have to write your own or use another secure form of transportation if you still want encryption over your UDP socket.
Key exchange is already not “just as easy” ![]()
If the Diffie hellman classes were implemented it would be very easy.
Exchange public parts, make server also send a signature to prevent MITM attacks. Boom.
But as for actually exchanging keys, you have two options as I see it.
- Implement your own EC diffie hellman as we did in the MLAPI.
- Use a webserver or something similar that talks to the server via SSL. Thus another transportation that is already secured.
Note:
TBH, feels like people are very scared of cryptography. For good reason. If you are inexperienced, you should not implement things yourself. But if you have implementations, like you do in .NET. There is no reason not to use them. Key exchanges and encryption is not complicated to use.
And if you are a somewhat experienced programmer with a lot of time on your hands you can implement these things, given that you use proper reference material and well-documented implementations and not just a Wikipedia article on the underlying math.
Because this thread has gained some attention recently. I would like to point out that my library MLAPI.Cryptography solves this problem and implements both ECDH and ECDH with RSA signing. Check it out here: GitHub - MidLevel/MLAPI.Cryptography: Unity friendly library for networked cryptography.