How do I digitally sign and trust a message in a distributed program I know can be reverse engineered?

StackOverflow https://stackoverflow.com/questions/964324

  •  12-09-2019
  •  | 
  •  

Question

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?

Was it helpful?

Solution

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.

OTHER TIPS

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.

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.

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.

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.

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.

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top