0

I'm developing a method for encrypting game data files which will be used in a game engine that I'm creating. The game data file will be encrypted with a private key and decrypted once loaded into the game engine.

The private key will be set manually in the engine (as a const) so that it is compiled into the engine. The trick, however, is obfuscating it in there so that your average Joe Bloggs can't (easily) find the key simply by disassembling and reverse-engineering the code.

struct Example {
    u_int8_t random1;
    u_int64_t segment31;
    u_int8_t random2;
    u_int8_t random3;
    u_int64_t segment3;
    u_int64_t segment14;
    // Etc
};

My idea is to store the key in segments which are jumbled together with randomly generated bytes. My question is this:

Is there any way to randomly generate a number in a C++ macro? The number must be randomly generated at compile time (or the random values each set to a random user-selected value), so any runtime functions are no good.

I'm open to any suggestions if there is a better way of doing this, but I definitely want the game data files encrypted with a private/public key pair, and the public key kept as private as possible.

orangething
  • 708
  • 5
  • 16

2 Answers2

1

Since you are generating a constant random number at compile time which will become baked into your program, I don't see a difference between that and simply hard-coding a random number (of your own choosing) into it yourself. I suppose with a macro you get a different random number with each compile. Is that really so critical?

I recommend doing something simpler: If the key were simply ASCII text (bits are bits, right?) you could use an inocuous-looking diagnostic string as your key and no one would notice it.

Still, security by obscurity is generally frowned on by experts in the field (they do a lot of frowning). If you are really doing public key encryption, it is perfectly OK to have the public key exposed. That is the point after all. It is the private key which must be kept secret.

If you really want to do this, then I would look at a random number generation algorithm, and unroll an iteration of it into a (large) macro that essentially takes a seed and evaluates to a large expression that yields a pseudorandom integer as its result. That should do it. If the seed were somehow derived from an unpredictable thing like the time of the compile (__TIME__), it just might work.

Randall Cook
  • 6,728
  • 6
  • 33
  • 68
  • 1
    Hiding the key is necessary. The danger isn't that someone might learn the private key, but that they might replace the public key with one of their choice, matching a different private key under their control. – Ben Voigt May 06 '12 at 05:05
  • The reason why I don't want to expose the public key is because it can be used to decrypt the game data file. The private key is kept separate to the file and the engine so that nobody can fabricate a game data file. Also the other half of preventing fabrication is what @BenVoigt just said. – orangething May 06 '12 at 05:08
  • But the idea about using `__TIME__` sounds like a perfect solution, coupled with a randomness algorithm. Thanks! – orangething May 06 '12 at 05:10
  • I would reconsider your aversion to letting people create game data files. A big factor in the success of DOOM and DOOM II were that people could make their own .wad files. They kept the game fresh. Better yet, provide an editor like Little Big Planet. Of course, if you have other reasons, then encrypt away. :) – Randall Cook May 06 '12 at 05:12
  • @Randall: If you have a multiplayer game, then letting some players play by different rules is very problematic. – Ben Voigt May 06 '12 at 11:52
  • 1
    @BenVoigt: If your security system depends on players's clients sending honest messages, I would be more worried about people reverse engineering your program's communication protocols than reverse engineering your program's rule file format and loading mechanism. – Robert Cooper May 06 '12 at 18:46
  • @Robert: I definitely agree. The same considerations apply to the communication link, though, if it's also encrypted. It all goes back to the fundamental rule of computer security/licensing: Once your code is on someone else's hardware, you no longer have control over it. – Ben Voigt May 06 '12 at 21:52
0

There's not currently any rand macro or template metafunction, but it could be created...with a lot of effort.

On the other hand, you could simply touch /dev/random as part of your build process, or some other random source, and create a header with the result. Include this header where you get a random number constant.

Edward Strange
  • 40,307
  • 7
  • 73
  • 125
  • Good suggestion, but is there an equivalent on Windows? Also would simply doing #include "/dev/random" be any good, or can paths not be specified like that? – orangething May 06 '12 at 04:54