ID:151718
 
If anyone has played Tomb Explorer and perhaps seen or participated in the small competitions that we held for it, you'd understand why its important that a saved map be secure to protect it from being modified for easy cheating. I'm sure its pretty much impossible to protect them from everything, I'd like to achieve a reasonable degree of protection so than an average-joe everyday file hacker can't easily cheat.

With Tomb Explorer, what I did was basically create several small files to store individual bits of data, such as map information, scores and layout, then I RC5-encrypted each of these so that they couldn't be tampered with, but so they could still be loaded individually rather quickly.

The problem with that though is that maps tend to take a rather long time to encrypt and decrypt, and nobody likes delays, especially in single player games. I'd also like to take the secure map saving and loading functionality to larger maps, and if Tomb Explorer's minuscule map sizes were creating delays with saving/loading, you can bet that larger maps would be exceedingly cumbersome to deal with.

So really all this post is for is to get other people's ideas on how to secure map files so that they can't easily be read or edited, but will still load and save quickly. Actually it would be kind of nice if BYOND's standard savefiles could be password protected to prevent them from easy tampering. But since that isn't the case...
Code a DLL which does all of the encryption and decryption for you via passing a filename to the DLL, and possibly the encryption key too. Native compiled code is most certainly going to be faster than BYOND-code.
How long does it take to encrypt 86 KB worth of data?

What is the size of the files you're currently working with?

Is the lag being created during the encryption/decryption phases, or the recreation of the map?
In response to Slurm
Two methods of modifying data (You don't "Hack" your own computer) are available to average hackers. The two methods are static and active data editing. In small file sizes with save states static is quite easy however the most preferred method is active data editing (Cheat Engine). Cheat Engine is able to quickly and easily locate numerical values. Where it falls short is in the check sum. If you just encrypt the checksum and nothing else you would be fine (Thats my theory based on my knowledge in the matter).

Also I really have no idea what you're trying to protect from "hackers", are you trying to implement legitimate contest winner checking or what?
In response to AJX
AJX wrote:
How long does it take to encrypt 86 KB worth of data?

About 17 seconds for 57kb in text format, and 33kb in savefile format.


What is the size of the files you're currently working with?

My test file is a 20x20x10 map, which I'm hoping will be rather small for the kind of maps I had in mind.


Is the lag being created during the encryption/decryption phases, or the recreation of the map?

Purely due to encryption.
In response to Slurm
Slurm wrote:
Code a DLL which does all of the encryption and decryption for you via passing a filename to the DLL, and possibly the encryption key too. Native compiled code is most certainly going to be faster than BYOND-code.

Only problem with that, aside from the slightly obnoxious one-time DLL alert, is that I don't have any experience programming DLLs.
Is there a reason you need the map encrypted rather than just secure? You could create a hash of the important parts of the map's contents and save it, then verify the hash on loading to make sure the map was unaltered. That would seem to cover what you wanted, and should be much faster than encrypting the whole thing.
In response to Foomer
Foomer wrote:
Only problem with that, aside from the slightly obnoxious one-time DLL alert, is that I don't have any experience programming DLLs.

Sorry, I made the mistake of assuming you were hosting a server of some sort that allowed players to keep a local copy of the save. If the players have access to the code that's encryptiong and decrypting, then there is no security period no matter what you do.
In response to Slurm
I was intended to make a basic library out of something similar to what Tomb Explorer uses for map saving and loading.
In response to Hobnob
Hobnob wrote:
Is there a reason you need the map encrypted rather than just secure? You could create a hash of the important parts of the map's contents and save it, then verify the hash on loading to make sure the map was unaltered. That would seem to cover what you wanted, and should be much faster than encrypting the whole thing.

Actually it occurs to me that I had thought of creating a verification system myself, and I just forgot about it. :P Thanks for reminding me, and yeah, that'll probably cover it.
In response to Foomer
Foomer wrote:
AJX wrote:
How long does it take to encrypt 86 KB worth of data?

About 17 seconds for 57kb in text format, and 33kb in savefile format.


What is the size of the files you're currently working with?

My test file is a 20x20x10 map, which I'm hoping will be rather small for the kind of maps I had in mind.


Is the lag being created during the encryption/decryption phases, or the recreation of the map?

Purely due to encryption.

Well I was doing some tests combining my map handling lib and RC5 encryption and I pretty much concluded that the only way to viably handle this in a speedy manner is to use a series of verification hashes to make sure nothing has been modified... But Hobnob already pointed that out. :( So yea. <_<
Okay, all I really need is to be able to do this:

1. Save and load reasonably large maps, perhaps 50x50x10 (25k tiles) fairly quickly. I'm not too worried about size as long as its fast.

2. I need to be able to verify that the map hasn't been modified since it was saved in an editor. If each map has a high scores value assigned to it, it needs to be able to verify that it hasn't been tampered with before updating high scores. It wouldn't be any good for someone to download a competition map, add a bunch of treasure and a pathway to the end, then play the modified map to get high scores...

It also needs to be able to save at least specific object variables, not just object types.

Any suggestions on how to pull this off?

I mean, I could just get the ascii value of every character in the savefile, but it takes around 5 seconds for a 20x20x10 map (4k tiles) using a function like this:

proc/GetStringValue(text)
var/value = 0
for(var/n in 1 to length(text))
value += text2ascii(text, n)
return value


So I think that isn't ideal.
In response to Foomer
You can use md5() on the entire file, which is going to be instant for anything. The trick is that you have to store the hash elsewhere because you can't put it in the file (as that would change the hash).
In response to Garthor
Garthor wrote:
You can use md5() on the entire file, which is going to be instant for anything. The trick is that you have to store the hash elsewhere because you can't put it in the file (as that would change the hash).

Well if you're going to do that, you could store it in two different savefile directories.

map
map_stuff
verify
md5(map_stuff)

Are there any easy ways to get around this though?
In response to Foomer
Not really. Hashes are very difficult to reverse, and even after you reverse them, you still don't get all of the information.
In response to Jeff8500
Jeff8500 wrote:
Not really. Hashes are very difficult to reverse, and even after you reverse them, you still don't get all of the information.

You can't reverse hashes. You can only produce collisions, or find out the input salt and produce meaningful hashes to go along with the changes you make. In the case of dynamic salt, you'd have to figure out how the salt is computed (in BYOND's case, this generally means you'd have to be of the small minority capable of reversing DM bytecode):
proc/Hash(text)
var/len = length(text)
return md5("[len][text][(len&0xF)<<3]")

Something like the above would be very hard for someone who doesn't know the DMB format to find, as a string extractor would be of zero value.
MD5 hashes aren't secure. They are "good enough", but people like me, who know how to deal with MD5 hashes are the only ones you have to worry about.

Even so, this can be countered with a decent bit of poking around. For instance, you can split each file into a random number of chunks, and hash those chunks. Then, you can put the chunk length into the file at the header. That way, the file's hash is changed. Then, you use your system to reverse the chunking and hashing. That way, if a map is changed by an unsuspecting player, and they don't realize that there are multiple hashes, you've got no issues with... say... deleting that character and calling them a filthy cheater.

Of course, with single player there are still many, many other ways to cheat.
In response to Ter13
There's no particular reason to nest security measures. Past the first one they're just basically "do you know what the security measures are?" If they don't, then the whole thing is moot (they wouldn't have reached this layer of security), and if they do, then they can just break through this one too.

It's like putting two locks with the same key on your door.

Also: "reverse that hashing" is impossible, as has already been mentioned.
In response to Garthor
Sorry, I guess I intended to say: "compare" instead of "reverse". Mixed up the verbs I guess. I thoroughly understand MD5 checksums, and their one-way nature, and don't need to be at all reminded of how they work.

However, I find your statement of there being no reason to nest security measures past the first to be extremely contradictory.

Because if you don't know what the security measures are, you can't break them. Dud characters, redirects, and PRNGs have been a staple of cryptology and file security since the advent of the computer age.

While the second layer may be moot most of the time, an external MD5 checksum is too easy. A PRNG-generated string of byte offsets creating MD5 checksums throughout the file will stop even the most determined cheater... Assuming he doesn't already know how you secured your files.

And this isn't two locks with the same key, Garthor, it's putting 1-N locks on a door with 1-N keys, then hiding the keys under random objects around the same door.

Trust me, it's frustrating enough to deter just about anyone.