This has been debated *eternally* in game circles since the advent of networked games, and I've followed these discussions for at least the last decade. The conclusion is always the same and is not disputable: in a broad-based, open competition (such as a web-based game for prizes, e.g. a casino website) you *absolutely* cannot trust the client no matter how many layers of encryption (which is designed for and protects against man-in-the-middle attacks) and obfuscation (which only slows, not stops) you apply.
Sure, those are a lot of suggestions for "whacky" obfuscation techniques (the statistical stuff is not useful as Tom pointed out), but ultimately that only slows. And really, if you're going to use obfuscation *please* invent your own, otherwise it's ineffective as obfuscation. Built it out of standard pieces (MD5 hashes, time windows, etc.) to make the implementation easier -- because you'll have to change it eventually. With the web, if you have a game that's at all popular *and* has a prize worth cheating for (or rather, worth *preventing* cheating for), then your energy is best spent trying to (a) work out *some* way to validate a score server-side that doesn't involve *trusting* the client, and (b) plugging in an obfuscation system that can be swapped out trivially and routinely. If security is *critical* then you'll need to run all the score-affecting logic on the server as I outlined earlier. If security is merely *important* and/or it's not possible to run all the logic on the server (such as an action game), then I'd go with a variation on the rotating, randomized obfuscator module I outlined earlier. Here's a variation on that: 1. Break out all of the score-centric game logic into an independent module (SWF). Make sure that anything that can affect the score (timing included!) is contained in that SWF. Hopefully this SWF will be fairly compact (it won't contain art assets or a lot of UI code, nor should it require any Flex framework stuff, etc.). 2. Write an obfuscation algorithm (encryption, hashing, shuffling, zipping, ROT13, whatever...). In fact, write as many as you can (I'd recommend at least a dozen). You'll need to create server-side equivalents of these as well (to verify the results). 3. Compile one version of your scoring SWF for each obfuscation algorithm. 4. For each scoring SWF, run it through something like SWFEncrypt to complicate decompiling as much as possible. It's not perfect, but it'll lower the number of script-kiddies out there who can attempt to crack it. 5. When the game loads up on the client-side it needs to connect to the server when a new game is started (not a new session, but each new game, i.e. each time the score is reset to 0). The server logs the new game starting, selects one of your obfuscation algorithms, assigns it a randomly generated unique ID, and passes it back to the client. Even better -- and I don't know if this is possible, but it *should* be, don't use SWFEncrypt on the scoring SWF until right before you send it to the user and have SWFEncrypt use a different seed value for its obfuscation; this ensures that the SWF's checksum (or any other fingerprinting the user could do on the SWF) can't be used to detect repeats in the selected scoring SWF. 6. The client uses the scoring module for the duration of their game. At the conclusion of the game, the scoring system returns its obfuscated result back to the server. 7. The server receives the response, looks up which obfuscation algorithm was used for that client (based on the unique ID generated in step #5), and it decodes the result. This method has several advantages: - The client can't prepare ahead of time to fake the obfuscation because it's randomly selected and (ideally) unrecognizable in binary form (CRC of the SWF, etc.). - The hacker's only recourse is to attempt and reverse-engineer the SWF during the game time window. If you've got a game that can't be run on the server because it's too "real time" then it's likely your time window is going to be small enough that reverse-engineering isn't feasible. - If the hacker hammers your server trying to collect all of the possible obfuscation algorithms, you can attempt to only send a random sub-set of your algorithms to any given IP to prevent/slow the hacker from sharing their results. Ideally, you would SWFEncrypt on the fly with a random seed so that the hacker would have to invest a large amount of time not only determining which obfuscation algorithm each "new" scoring module used but how many scoring modules there are in total (which, without the random seed or IP subsets would be possible without reverse-engineering). Troy.