1
\$\begingroup\$

I am using Java to write a moderately simple video game and I need to transfer some large files (edit: Live game data and possibly assets.) between the client and the server. I need to decide whether I want to encrypt the data even though no sensitive information is being transferred. If I were to encrypt the data what method would be the best? Also, does encrypting data make cheating harder?

\$\endgroup\$
  • \$\begingroup\$ are the large files assets (like textures and models)? \$\endgroup\$ – ratchet freak Dec 10 '14 at 11:08
  • \$\begingroup\$ No they are not assets. \$\endgroup\$ – user55958 Dec 10 '14 at 11:53
1
\$\begingroup\$

Encrypting the data each player receives makes cheating and ripping of assets a bit harder, but not impossible. The data needs to be decrypted by your game client anyway, so the encryption algorithm and key must exist on the users machine. That means the users have everything they need to decode the network traffic. So you only add a layer of security through obscurity, which isn't any real security.

It could get interesting, however, when you have cheaters who are eavesdropping or even manipulating the connection of other players to get an advantage. Attacks of that level of sophistication are quite uncommon in gaming, but certainly not inconceivable, especially when cheater and target are on the same network. When you encrypt the data for each player separately with a key only known to the receiver, you can prevent that.

But make sure you use a cryptographically secure algorithm. There are libraries available for most common algorithms in most programming languages. In Java, you even have hard encryption in the standard library.

\$\endgroup\$
  • \$\begingroup\$ Yeah, that was my first idea. \$\endgroup\$ – user55958 Dec 10 '14 at 11:53
2
\$\begingroup\$

I see the following reasons to encrypt data:

  1. Protect your users' actual sensitive data by adding to the amount of encrypted traffic. If hackers have to wade through not sensitive game assets, they're much less likely to find a user's actual sensitive data.

  2. Protect your servers. Using asymmetric key encryption (like TLS, what people still commonly refer to as "SSL") usually ensures that the user is not tricked into giving their password to a man-in-the-middle, who can then use it to get a level deeper into your server. (assuming you verify who you're talking to)

  3. Protect users' in-game purchases, e.g. in so-called "free to play" games. If your game has micro-transactions, attackers like to hack a user and transfer in-game items to another account under the attackers' control, where it can then be sold. Proper encryption makes it harder to spot the password in the traffic.

  4. Protect yourself from stupid ISPs. Some ISPs (Hotel Wifi) look at clear-text traffic and modify it. E.g. replacing banner ads with their own. Also, certain mobile carriers will re-compress image files to save bandwidth. If your game assumes all assets are true-color PNGs and they convert them to 4-bit to save space, your game will crash. Using TLS encrypted connection ensures that the files your server sends are what your client gets, because ISPs can't introspect them. This is even more important if your downloaded assets contain scripts that an attacker could replace to run malicious code on your user's machine (esp. if you have automatic patches to your game engine that gets run as root via an installer, or so).

Whatever reason sways you, do not roll your own encryption. It's too easy to subtly get something wrong and do a lot of work but leave the barn wide open. Go with the established standard (i.e. use a TLS connection) to protect the data in transit, and verify the server certificate against its public certificate to be sure you're talking to the right machine (that's a thing commonly forgotten).

Regarding cheating: Your client has to be able to decrypt the data it gets and make requests. The client runs on the user's machine. If the client app can do that, it can do anything else. Reverse-engineering that is trivial. Is it harder to have any encryption compared to plain text? Sure. But it'll barely deter anyone. If your game has a network component, make all the game-relevant calculations happen on the server, and only transfer data to the user that they should have at this point in the game.

For speed, you can have the client pre-calculate the likely result of an action and display that while it asks the server to verify that and actually write it into the server's storage. If someone is trying to cheat, the server will thus catch it and the client's display will immediately reset to the "un-cheated" state.

Encryption is not an anti-cheat measure.

\$\endgroup\$
  • \$\begingroup\$ But, no sensitive data is transferred. \$\endgroup\$ – user55958 Dec 10 '14 at 19:46
  • \$\begingroup\$ @Benjamin Re item 1? Not by your app. But by other apps on the user's computer. If you send unencrypted, hackers know they can just ignore your app's data and home in on HTTPS connections to hack your user's home banking. If you mean Re item 2, where do you keep game state, and why do you need to download anything at all if your game is all offline and doesn't have a way to associate the user with their data? \$\endgroup\$ – uliwitness Dec 11 '14 at 18:02
  • \$\begingroup\$ It is a multiplayer game but no sensitive data is transferred. \$\endgroup\$ – user55958 Dec 11 '14 at 22:34
-4
\$\begingroup\$

Do you care if people can get your assets? Do you transfer gameplay data? If any of the questions is true, then encrypt.

I would use XOR cipher. It's super simple, super efficient, not super secure but you apparently don't care (it WILL make cheating harder of course, if you send gameplay data though). It works with streaming data, and the encryption is the same as the decryption -- just apply it twice to get the original.

XOR cipher C++ code example:

char * key = "whatever";
int keylen = strlen(key);
int i, string_length = strlen(string);
for(i=0; i<string_length; i++)
    string[i]=string[i]^key[i%keylen];

where "key" is your cipher key. What it does is for each character of your string, you select a character from your key and you XOR it. when you XOR it again you get the original. Replace "whatever" with .. whatever :)

\$\endgroup\$
  • \$\begingroup\$ The answer to your first question is not true as it is semi-open source, the answer to your second question is true. Is it possible to implement in Java or would I have to use some sort of bridge? \$\endgroup\$ – user55958 Dec 10 '14 at 11:36
  • \$\begingroup\$ Ok, then encrypt the gameplay data at least, or more, to confuscate what's gameplay data and what's not :) It is possible to do it in Java. I'm not a Java coder but it's straightforward : a xor operator and basic string handling. I provide a C++ example. \$\endgroup\$ – Babis Dec 10 '14 at 11:42
  • \$\begingroup\$ -1 A simple XOR cypher is so easy to crack that even an amateur hacker won't be stopped by it for long. When you use encryption, at least use a cryptographically secure algorithm. And no, it's not harder to implement. You just have to use a library. \$\endgroup\$ – Philipp Dec 10 '14 at 11:46
  • \$\begingroup\$ Thanks. @Phillip Would it still make cheating harder? \$\endgroup\$ – user55958 Dec 10 '14 at 11:49
  • 1
    \$\begingroup\$ @Benjamin Depends on how skilled the hacker who programs the cheat. It would take them between a few minutes and a few hours longer to reverse-engineer your network protocol. So you can expect that a simple XOR encoding will give your community at most one day more before the first cheats are offered for download. \$\endgroup\$ – Philipp Dec 10 '14 at 11:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy