ForumsProgramming Forum[as3] saving with .sol protection

11 13378
weirdlike
offline
weirdlike
1,299 posts
Prince

Saving is pretty simple stuff

private var saveSlotData:SharedObject;
saveSlotData = SharedObject.getLocal("saveSlotData"

which can be used in a single function

private var saveSlotData:SharedObject = SharedObject.getLocal("saveSlotData"

then you write anything you want, like maybe your cash and lives variable

saveSlotData.data.lives = lives;
saveSlotData.data.cash = cash;

then save the written data and close

saveSlotData.flush();
saveSlotData.close();

getting the data back is simply reversing the above lines but without flush

private var saveSlotData:SharedObject = SharedObject.getLocal("saveSlotData"
lives = saveSlotData.data.lives;
cash = saveSlotData.data.cash;
saveSlotData.close();

---------------------------------------------------------------------------
Now for the encryption key.

There are a few sol editing programs out there, which people use to manipulate local save to have better stats, more money, etc. etc.

I am curious as to other methods that are out there, but a method I have found is by taking all the saved data and generating the MD5 hash and saving the hash alongside the data. Then when the data gets loaded again check the MD5 hash of the data with the stored hash data and if they match, the file is good to go.

first make sure the data is saved

saveSlotData.data.lives = lives;
saveSlotData.data.cash = cash;

then generate the key with the saved data by using the tool

var generatedKey:String = SOLTool.getKey(saveSlotData.data.cash, saveSlotData.data.lives);

you can use as many arguments as you need then save the key with the data

saveSlotData.data.encryptionKey = generatedKey;
saveSlotData.flush();
saveSlotData.close();

at that point when you go to load the data just generate the key again using the same saved data

var newGeneratedKey:String = SOLTool.getKey(saveSlotData.data.cash, saveSlotData.data.lives);

then make the comparison with the saved key

if(newGeneratedKey == saveSlotData.data.encryptionKey)
{
trace("matching&quot
}

if the key does not match then you know that the .sol file has been edited. At that point you can take whatever action you want

You can find my MD5 hash tool HERE just put the class file in the same folder with your other classes and use the above function. Slightly edited by me where everything is compiled into a single class with a single function that uses as many variable's as you want. A current project that I am working on contains 86 variable's all different data.

You can find the full classes for MD5 and SHA 1 hashing, Image encoders, and JSON serialization as well as general String, Number and Date APIs at as3corelib. This will need everything to be put into a string then apply the string to the hash tool and save.

If anyone has a different method, by all means please share, or if there are any questions I can assist in any way to get this working.

  • 11 Replies
RedN
offline
RedN
141 posts
Duke

You can implement anti-cheat protection,but you cannot make something that is 100% secure (only server-sided stuff is),many people attempting to cheat will give up at this point,but in fact,there are many ways to do it,you can protect your sol files,what about your variables at run-time?what about your swf file?

If your game is good enough,it will probably make it to websites that feature hacked games,no matter on how you try to protect it (not something to complain about,you'll get a few thousand extra plays).

But you're right,most cheaters are just kids who just learned that it's possible to get free money in any game they want,and those won't even think about another way to cheat if their first attempt fails miserably.

Your algorithm looks nice,but many game devs don't use anything to prevent save file editing,because they spend extra time doing stuff that normal players won't even notice.

weirdlike
offline
weirdlike
1,299 posts
Prince

what about your variables at run-time?what about your swf file?


While I can think of a few things to remedy these issues it is not what I designed this topic to approach. And while nothing is truly protected when it is stored locally, not everyone has the resources for server implementation. So I geared this to be a money free solution. Personally I feel that if there is an issue (like local manipulation), it should be addressed. Programmers should be aware of these editing programs and use them to cheat at their own games to get a better understanding of how to protect from them.
RedN
offline
RedN
141 posts
Duke

In your example code,someone who wants to edit the sol can do one of the followings:
1- Modify the values,and calculate the encryption key manually to make a valid sol file.
2- Modify the routine that checks for valid sol files (by making the condition always true,for example).
Here is a more secure approach,but you pay the price in readability,you save all your data as one entry,named 'savestring',encoded with base64:
To save:

var b64:Base64Encoder = new Base64Encoder();
var savestring:String = ("7561348741"+lives+"DEA0C"+money);//Those are just random alphanumeric chars
b64.encode(savestring);
saveSlotData.SaveString = b64.toString();
saveSlotData.flush();
saveSlotData.close();

Now,to load:

private var saveSlotData:SharedObject;
saveSlotData = SharedObject.getLocal("saveSlotData"
var b64:Base64Decoder = new Base64Decoder();
b64.decode(saveSlotData.SaveString);
var savestring:String = b64.toString();
var lives:int = int(savestring.split(savestring.indexOf("DEA0C&quot+5,-1));
var money:int = int(savestring.split(10,savestring.indexOf("DEA0C&quot));

It's not as simple,but even if someone decrypts the save string,he will find something like this: (lives = 5 ; money = 1562
"75613487415DEA0C1562"
I don't use AS3 much,sorry if my code looks messy..
Again,this isn't very secure.
You can also use bitwise operators (binary xor for example is widely used for encryption).

weirdlike
offline
weirdlike
1,299 posts
Prince

It is to my understanding that you are proposing using Base64Encoder/Base64Decoder to generate a string then store a single string. Ideally I would want to use a method exactly like this instead of comparing keys, as MD5 is a one way algorithm it cannot be decrypted. I will do my own research on this suggestion and see what I come up with but for now Ill address your comments on my method.

1- Modify the values,and calculate the encryption key manually to make a valid sol file.


This is a very real scenario. First the person would have to know that it is in fact MD5 and not SHA 1 or the likeness. Then they would need to know the proper sequence and have the ability to generate the MD5 hash. Suppose they have this already figured out. This is easily deterred by using a password that is embedded into the .swf itself, separate from the .sol file.

var generatedKey:String = SOLTool.getKey("superFancyPassword", saveSlotData.data.cash, saveSlotData.data.lives);

So unless if they knew exactly what the password is and the correct sequence, they will never be able to get the correct algorithm.

2- Modify the routine that checks for valid sol files (by making the condition always true,for example).


The only way this could work is if the person could make the changes at run-time, or decompile the .swf, which I think will derail from this topic. I might approach these scenario's sometime in the future, but it wont be until I have a better understanding of how they work and have a method to deter from them.

In any event, this would require a certain level of skill in programming. Someone who can recognize these security measures that are put in place and do a manual fix. It is not something that a simple on-line .sol editor would be able to provide.
RedN
offline
RedN
141 posts
Duke

So unless if they knew exactly what the password is and the correct sequence, they will never be able to get the correct algorithm.


They can decompile your game,check the algorithm,and use it to make valid keys,they can even use something like [url]http://hashkiller.co.uk/[/url].

In any event, this would require a certain level of skill in programming.


Yes,but if it's a quality game,then you can expect experienced programmers to play it,sometimes they submit their cheats as videos on Youtube,and get thousands of views.
If you make anything new,please share.
weirdlike
offline
weirdlike
1,299 posts
Prince

They can decompile your game,check the algorithm,and use it to make valid keys,they can even use something like http://hashkiller.co.uk/.

Again the topic isn't geared for .swf protection... Also that link is not a decrypter website. What they do is compare the hash with the already existing hash database on the site.

HashKiller.co.uk allows you to input an MD5 hash and search for its decrypted state in our database

This is literally what they state on their website.

I would like to see anyone who can crack this hash

4cc5144f2b002c86ea3af770bbc400c0

password = ???
string = "you got me"
lives = 1
boolean = false

Using my hash file above, all the data is there except the missing password

RedN
offline
RedN
141 posts
Duke

Oops,sorry for the wrong link,no need to decrypt,they have the variables,and how the hash is made so they can make the hash with [url]http://www.md5online.fr/md5-encrypt.html[/url]

Then fill the resulting hash in saveSlotData.data.encryptionKey,and the new sol file is valid.

weirdlike
offline
weirdlike
1,299 posts
Prince

I was interested in http://www.md5online.fr/md5-encrypt.html and quickly tried the comparisons, unfortunately it does not work with anything more than a single variable, or maybe I am not typing them in correctly I don't know. As far as the encryption goes the algorithm is the same, so theoretically it would work which is why I suggested using a password that is stored in the .swf itself. A single variable that is unknown to the intruder editing the file, without it they cannot generate a match.

weirdlike
offline
weirdlike
1,299 posts
Prince

I looked into the base64 method you suggested @TheRed555 and it does the job. I used THIS class from code.google. You are correct in saying that pay the price in readability, tho it is not that big of a loss there. This method you also suggested var savestring:String = ("7561348741"+lives+"DEA0C"+money); actually says a lot to me, as an internal key decryption that is required to read the data.

RedN
offline
RedN
141 posts
Duke

I found another simplier way,uses no external classes,less ressources,and with a much shorter key (which is not a string,but an integer):
To save:
var ___:int = (money*2)^lives^(armor*3)^324;//any arithmetric expression
// remember that 324 is like the 'assword' in your previous code
saveSlotData.data.___ = ___; // using this identifier to confuse the hacker
saveSlotData.data.lives = lives;
saveSlotData.data.money = money;
saveSlotData.data.armor = armor;
saveSlotData.flush();
saveSlotData.close();

Now to load:

var ___:int = saveSlotData.data.___;
var newkey:int = (saveSlotData.data.money*2)^saveSlotData.data.lives^(saveSlotData.data.armor*3)^324;
if (newkey == ___)
{
// load the variables from the sol file
}
else
{
// Set those vars to default values,or start a new game
}

This way,if armor = 97 ; money = 214 ; lives = 4 then the key is 463,if lives change to 3,the key changes to 456,if lives = 2 then the key is 457,does it make any sense?
They need to know the formula (money*2)^lives^(armor*3)^324; in order to calculate the key correctly,and the expression can be more complicated.
if armor = 97 ; money = 4000 (changed by an attacker) and lives = 4 then the key is 7971.
(Remember,you can't xor strings,but you can encrypt them,for strings,use it's size in the expression (or the hex code of one of its characters),for booleans,represent them with 1 for true and 0 for false).

weirdlike
offline
weirdlike
1,299 posts
Prince

Definitely simpler, and much like the method I first suggested but instead creating your own calculations and using them as the key for comparison. Personally I prefer methods that I can fully understand and code myself over external classes.

Showing 1-11 of 11