Encrypted communication with Kryonet

108 views
Skip to first unread message

superjugy

unread,
Apr 17, 2018, 4:13:25 PM4/17/18
to kryonet-users
Hi,

I've been searching for this topic but i found very little information or very bad advice. This is my use case:

  1. A user should connect to my server in a secure way and send a username and password for authentication.
  2. The server should validate the username and password and let me continue if valid.

Very simple use case right? and still can't find a simple example that gets it right. I read this post for example: https://groups.google.com/forum/#!searchin/kryonet-users/encrypt|sort:date/kryonet-users/PYtZYQH6Izk/6oKcNDdAAwAJ. The final comment is recommending to "Encrypt the password on the client, then send it over the network". The first question I ask is "what if there is a man in the middle?". The man in the middle will be able to get the message and get the user name and encrypted password (since the message itself is not encrypted, just the password) and since the comment just suggests to compare this encrypted password with the database stored value, the man in the middle basically just got your password... that is why the password is encrypted server side with a Salt and THEN compared to the database value. All it has to do now is have a modified client that sends the password directly and enter the intercepted password to login.

And before anyone says that the client could use the public key to encrypt and decrypt and server use the private key. Asymmetric encryption is slower and, in the case the private key is compromised, any intercepted message is now readable (i.e. it is not forward secret). Even on https, the asymmetric key is only used during the handshake to generate an ephemeral symmetric key.

Since Kryonet doesn't support TLS, the only flow I can think of is this:

  1. Have a separate login server that works with https (TLS) and gets the user name and password.
  2. Validate the username and password and return a symmetric key and token.
  3. Connect with kryonet and send the token so the server can (somehow) expect any further calls from this client to be encrypted with the symmetric key.
In theory steps 1 and 2 are secure automatically because of https with TLS. and step 3, even if a man in the middle intercepts the token, he won't have the symmetric key and won't be able to neither spy the following communications nor pretend to be another client since it won't have the key to decrypt the messages or encrypt fake messages.

My understanding is that Kryo does have a way to use a key to encrypt the messages. My question would then be, is it possible to have different encryption keys for each connection and is it able to enable encryption after the token is received.

Also, if there is any flaw in this design, please let me know.

Thanks,
Superjugy.

Nate

unread,
Apr 20, 2018, 6:42:23 PM4/20/18
to kryone...@googlegroups.com
If you can use TLS through a different channel, that may be easiest and less likely you get it wrong. If you want to do it through KryoNet, you'd have to do it all yourself.

You are in control of what you are sending with KryoNet. Eg, you could extend or replace KryoSerialization to manipulate the bytes sent and received. You could use different keys for each connection, or any other scheme you like.

Cheers,
-Nate


--
You received this message because you are subscribed to the "kryonet-users" group.
http://groups.google.com/group/kryonet-users
---
You received this message because you are subscribed to the Google Groups "kryonet-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to kryonet-users+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Joachim Durchholz

unread,
Apr 21, 2018, 3:21:54 AM4/21/18
to kryone...@googlegroups.com
Am 17.04.2018 um 22:13 schrieb superjugy:
> The final comment is recommending to "Encrypt the password on the
> client, then send it over the network". The first question I ask is
> "what if there is a man in the middle?". The man in the middle will be
> able to get the message and get the user name and encrypted password
> (since the message itself is not encrypted, just the password) and since
> the comment just suggests to compare this encrypted password with the
> database stored value, the man in the middle basically just got your
> password... that is why the password is encrypted server side with a
> Salt and THEN compared to the database value. All it has to do now is
> have a modified client that sends the password directly and enter the
> intercepted password to login.

The advice obviously doesn't work.
What one does is establish a secure communications channel, then send
the password. Or use a challenge-response protocol, which doesn't even
need an encrypted connection.

Doing this right requires zero-bug coding, so it's usually better to use
an easy-to-use, battle-tested library. The JDK does have some
security-related libraries, so you should build on top of these.

Nate has recommended manipulating bytes as they go over the line. You'd
have to code all the asymmetric and session key management yourself, or
use the library functions exactly right, and you'd still have a high
chance of overlooking something and opening your software to attacks.
IOW I strongly disagree that that's a viable approach.

> Since Kryonet doesn't support TLS,

Heh. Given the complexities of setting up a secure connection by hand, I
suspect it's easier to write the code that adds that support.

> 1. Have a separate login server that works with https (TLS) and gets
> the user name and password.
> 2. Validate the username and password and return a symmetric key and token.
> 3. Connect with kryonet and send the token so the server can (somehow)
> expect any further calls from this client to be encrypted with the
> symmetric key.

The login server would have to tell the service server which tokens are
valid.
Single Sign-On protocols like OAuth, SAML, Oz etc. all work that way, so
this is definitely doable.

You'll have an extra complication in your overall setup though, and if
you do not control the physical hardware that connects the two servers,
you'll have an extra connection that needs to be secured, i.e. the
problem is still there, just in a different corner.

Just my thoughts.
Regards
Jo

superjugy

unread,
Apr 21, 2018, 12:26:34 PM4/21/18
to kryonet-users
Yeah. I would obviously prefer if there was this kind of support out of the box in kryonet so that I don't mess it up.

I also thought about oauth, but oauth if I remember correctly still requires https (at least for the most basic username and password approach). The problem is not the authentication protocol. It's the transport itself (which kryonet is providing) which is vulnerable.

As for the login server and service server being under the same control, yeah I would assume they are in the same lan and they can trust each other. We can even simplify the example and assume they are the same server and that there is a load balance infront of the game server that just redirects traffic to the different app servers.

Nate

unread,
Apr 25, 2018, 6:25:59 AM4/25/18
to kryone...@googlegroups.com
On Sat, Apr 21, 2018 at 9:21 AM, Joachim Durchholz <j...@durchholz.org> wrote:
Nate has recommended manipulating bytes as they go over the line.

​I gave two possible solutions and zero recommendations.​
 
You'd have to code all the asymmetric and session key management yourself, or use the library functions exactly right, and you'd still have a high chance of overlooking something and opening your software to attacks. IOW I strongly disagree that that's a viable approach.

​It is certainly viable.​ Which is the least risky approach is a separate consideration.

​Cheers,
-Nate​

Reply all
Reply to author
Forward
0 new messages