...I have read a few threads on here that have discussed various methods and was just looking for some feedback on a proposed solution we came up with. In one of the threads a comment was posted recommending a public/private key which sounded great, this is what we were thinking...
Client Side - 1. Key is stored inside of Flash swf which is encrypted using 3rd party tool. 2. High score is hashed along with high-score value (EX: md5 ('ourSecretKey' + 200)) 3. This value is sent via AMF to a PHP script on the server, along with the high-score (200)
Server Side - 1. Server receives data and hashes the passed high-score (200) + secret key ('ourSecretKey' stored on the server as well as in Flash) and checks against the passed hash if the value is a match it allows the high-score to be entered, else FAIL.
I know this isn't a foolproof solution but would this be acceptable? I mean would this be sufficient security on a high-score form for a simple online Flash game? Thoughts?
Thank you in advance!
Bah I knew I should have mentioned SHA instead :)
If I do use something like a swf encrypter application to encrypt the swf code wouldn't that at least make it quite a bit more difficult to get at the key stored in Flash? I would think that without that key (or at least without getting to it easily) it would be a huge pain to figure out what was being used to generate the hash that is sent off to the server.
Something like this is what I was thinking of: SWF Encrypt
Thank you all again for these answers, this is amazingly helpful. Oh and this will just be a simple Flash game sent out by a client to customers, something fun to pass time at work over the holidays.
Wow
Pretty hard solutions 8).
I implemented system like this once. Although it won`t work for every game out there...
You should replay the game on server. When user play -- you store "state changes" and then simply feed it to you game in some kind of "replay" mode.
If the distribution of your game is limited and there's no real money/bounty involved for the players to win, your original scheme is probably enough.
Using SWF Encrypt will likely make it a little bit more difficult to extract the key, and it could be a good tool to use even in a more advanced system as well. But if you have a real public/private key scheme (e.g. RSA), it's really a moot point since the public key isn't a secret, it's not supposed to be. Still to prevent most people from editing the code and tamper with the scoring system, SWF Encrypt is probably a good enough choice.
Just to make you a bit more paranoid I wrote the following as well:
The problem with SWF Encrypt, as with most other similar tools, is that it must still be possible to execute the script on a (possibly compromised) machine. So all information must be available on said machine. Compare that with a classic use of cryptography, sending messages:
When you send an encrypted message, you typically trust the source and the destination, so both of these have the key to decrypt the message. What you don't trust is the courier, or at least not that your enemies will not intercept the courier. So the courier does not have they key and your message is safe.
Your problem is instead that in your case you trust the destination (you) but not the source (the client) or vice versa. Still you need the source to be able to encrypt the message since you trust the courier even less. So the source needs to have all information to encrypt and decrypt messages in order to function. Your problem is that you cannot see the difference between a "good" source and a "bad" source.
What I mean is that since the code must still be possible to run on a client, the information to do so must be fully available, albeit possibly in obscured form. A hacker could for instance create her own ActionScript compiler that transform the obfuscated ActionScript code into something readable and make appropriate changes. Difficult but definitely doable.
Yet this level of sophisticated attacks will most likely not be a problem for you, if you have a limited distribution and no real bounty to win.
I don't see any advantage of using the solution, Kent mentioned. As a client, I can request that server side created key. Ok I can't use it more than one time, but i don't have to ... every time I need one i just request it.
There is one and only one 100% working way of encrypting the scores: recording the replay.
But not just ANY replay, ideally you should only record the user key presses and space between them. This way, even if someone tampered with the source or dynamically with RAM, replay played on the server will find the problem.
This solution, unfortunately, requires a massive amount of work to be possible. For simplicity You can just manually validate all scores (or the best scores) and you are happy. Nevertheless you still have to avoid some things:
And possibly more.
This defense is, however, simply unbreakable. And takes time to code :D.
The answer to your question is, it depends. It depends mainly of the estimated popularity of your game.
From a security perspective, your solution is about as secure as sending the highscore in cleartext. What you're doing here is called security by obscurity, which, according to who you listen to may have its benefits in some cases. In this case it's probably that Joe the average user would not likely be able to crack it himself. For anyone with some l33t h4xxor skillz you might as well send it all in cleartext. If all you want is to stop Joe, then it's probably enough, at least until someone creates a fake client for Joe to download (which depending on the popularity of your game could take anything from a couple of days to never (or faster if it's WoW)).
A better solution is the one given by @Kent Fredric. However as it says it doesn't solve the problem of someone creating a fake client. A solution to that might be something like this:
This will guarantee two things:
But there's still one serious flaw to this scheme. There's no way of knowing that the game was in fact actually played. If the client is compromised, the list could just be a prefab of a "perfect game" that is sent to the server. It's not possible to directly tamper with the scoring system, but with enough effort someone will most likely be able to create a list of actions that comprise a "perfect game".
However it gives a little bit stronger guarantee than just using the solution in Kent Fredric's post. To solve the whole problem would mean that you must validate the client somehow. This is very difficult since most ways of doing this are easily circumvented.
Finally I just had to comment on your choice of hash algorithm: MD5 is a great hash algorithm for those still living in the nineties. For the rest of us I recommend SHA-2 or at least SHA-1.