views:

202

answers:

8

The problem in brief: I develop an application (for example a game) which is distributed in binary form. The game calls home and sends the user's high score as a message to an online game server.

What I'd like to do is digitally encrypt and sign the message so that I can trust it hasn't been tampered with.

Public key cryptography relies on each end of the conversation having a secret each, but I can't rely on my software not being reverse engineered, and the private key discovered.

Is there a secure or secure enough way of digitally signing (the encryption part isn't necessary in this case) a message from my distributed binary application when I know it can be reverse engineered?

A: 

No. For the client software to digitally sign it, it must have the private key. And if the software has the private key, the user can discover (and potentially abuse) it.

Matthew Flaschen
+3  A: 

In short: no... there is no fool-proof solution to this. The problem is that the application that sends you the highscores is running under the control of the person you don't "trust" in this transaction. If they can reverse-engineer the code, then they can alter the content of any message before it is signed.

jerryjvl
+1, but I believe that you have the question wrong: it seems that he's not asking about before signing. Or maybe he is... we'll see in another 2 mins :)
Yar
I guess the only solvable permutation is if he is concerned that a man-in-the-middle might tamper with people's scores... but I cannot imagine why a man-in-the-middle would care about some random gamers' score...
jerryjvl
Good point... as you say, that's the only case we've got the technology for :)...
Yar
A: 

In short, public key cryptography is made for this. The secret is not in the software, but rather in an external certificate that cannot be tampered with.

Thunderbird and other open source mail apps use public key cryptography for just that: the code is open source, but the certs are secure.

Edit: I'm reading through the question again: it's not clear what you mean. Cryptography would be used so that the messsage cannot be tampered with AFTER sending. Before sending, if your app is vulnerable (which it is), then ALL messages sent from the app are questionable.

Edit This answer is wrong, but I've left it here since it helps to understand this thing. See the comments...

Yar
The difference is that in the case of Thunderbird, the user is trying to protect the data,... in this case he is trying to prevent the user from manipulating the data, which is not possible unless you somehow manage to take away their control over their own hardware.
jerryjvl
Good point. I'll make this a CW since it's a wrong answer :)
Yar
Didn't mean to trample all over this question and its answers... but considering how much misunderstanding there is about what is technically possible in this field (*cough*RIAA*cough*MPAA*cough*), I thought I'd best take quick action ;)
jerryjvl
+1  A: 

Once the code (no matter - source, intermideate language, or machine code) of your program is in someone else's hands they can do whatever they want and you can't be sure that they don't misuse it. To make misuse harder use all possible ways to make reverse engineering harder, but this won't guarantee you against misuse.

sharptooth
+1  A: 

You just can't. There's no real solution to this problem, just more and more obfuscations and tamper checks (IMHO, it's just a waste of time). Hypothetically, every program can be reverse-engineered, emulated and tampered. There's nothing you can do against that.

The only way I can think of keeping the game results safe from tampering is to send some sort of game recording which can be replayed and score verified. This does not protect your game from being played by a robot, though. And this applies only if your game's world is completely deterministic.

drdaeman
A: 

Use some known algorithm,in my applications I use blowfish.But that's not what makes it safe.

Games usually have a process for checking the idenity of the program connecting to the server,the process is called "Handshake process".The server sends a packet,which conctains values and an encrypted(the client knows how to decrypt it) blowfish key.The blowfish key received from the server is random on each connect.This is the first part of the handshake.

The next part is encrypting a calculated integer based on the values received on connect(which are random) and then encrypt it with blowfish.

When the server receive that packet,the server sends the same packet,which is encrypted with the new(final) blowfish key.The client has to find out that key by decrypting it with the old blowfish key and then do calculations with the values received from the first packet.

This is the handshake process,after it's finished you can send your score on the same principal(or perhaps put it inside the handshake and send a fake packet after the handshake is done to fool reversers).

It's too much to do,but it's either too much for a reverser.

Another way to solve your problem is to add a two byte(word) security value(CRC) based on the packet content with your own calculation.The server will check that value and if its invalid -> Disconnect.

John
"the client knows how to decrypt it" than the reverse engineer also knows how to decrypt it, rendering your "method" useless. The logic which "hides" the encryption key by a scheme using the response values can also be deciphered by the attacker, it just makes replay attacks harder and adds to the puzzling for the attacker, but surely not impossible.
Davy Landman
Security through obscurity is no security at all. :)
Bob Somers
Look at which things the client knows how to decrypt.The client must know something,at least one algorithm.That doesn't make it useless,but it confuses the reverser.Blowfish + CRC is pretty much enough for sending score.
John
Reversing the security of a decent mmorpg will take at least a week and what I described above is the security of most mmorpgs.They can't add anything more than that,but pack the executable with a commercial protector.Would you spend a week reversing a low-level game?
John
Reverse engineering is much more interesting than grinding. But why would a mmorpg client even have to send scores? Better is to program the game servers to directly keep track of scores and other important stats.CRC is trivial to break, Why would any serious developer want to use that?
Accipitridae
A: 

Good question! Plenty of people here have already said it - you end up needing to build a key into your app which potentially is retrievable by reverse engineering.

Have a read up on Trusted Computing. This is built around a public/private key built into your PC - which your PC will never allow you to access. Memory curtaining / Sealed storage would make it difficult for an attacker to try discover a key delivered to your app.

russau
A: 

No, not in general. You face the problems mentioned by the other comments.

The question becomes one of cost. Is the cost of cracking a protection system higher than the value it is protecting? And what is the cost of recovering from a successful break-in?

Since a high score table is generally not a high value target, you might want to try any of these:

  1. Along with the high score, send some information on game state; playtime, level, bonuses collected, etc. Encrypt/obfuscate this data. This will help the server determine whether the high score could theoretically be valid. Ignore any highscores which are obviously fake.

  2. Send the high score using encryption with a shared secret.Don't store the shared secret as plain text in your app. Preferably, use an algorithm to calculate it in realtime.

  3. Obfuscate your client code.

  4. Store high scores with client IP addresses and a timestamp.

alp