views:

300

answers:

9

I want to be able to create a file, distribute it to an end-user, but prevent them from making modifications to the file.

Now, obviously, I can't actually stop anybody from modifying the file - so my approach is to detect and reject the file if it's modified.

My intention is to generate a salted hash of the file contents and append it to the file. On reading, the hash is verified before reading the rest of the file. The downside of this is that I have to distribute the fixed "salt" in the executable which reads the file. Obviously I can obfuscate it to some extent, but that still feels like a weak link.

Are there any better approaches to solving this kind of problem?

+1  A: 

Not if you want a 100% solution. Just look at the movie and music industry. They have tried and failed for many years now :)

I think your solution is good enough. To make it harder to modify the file you could encrypt it, but then they can't read it, so it will only work if that is an ok limitation.

Magnus Westin
He's not trying to stop people from copying the file just from changing it.
Omar Kooheji
I know, but its equally futile.
Magnus Westin
A: 

Depending on what kind of file you want to protect, you can use some document management tool. Adobe PDF has tools for that. Furthermore, if you host your application on a application server or webserver, users can't access and modify the code. This way, you could have a database of hashes at the server-side, of files you want to protect.

Of course protection is only as good in how much time and effort your users would want to (or can) invest in breaking the protection.

+4  A: 

If your application runs on the user's machines, they could always patch the binary so doesn't even do the verification, rendering all your hard work useless :-)

Even a server side solution can be bypassed by sniffing the traffic. So then you need to one up them and use SSL. And then they just patched the binary as above, and there goes that. So then you employ various measures to obfuscate your binary, and your users whip out a disassembler like IDA PRO.

The question I would be asking myself, were I in your position, would be "If I get into an arms race with my users, would I win?". If the answer is no, then I won't waste my time.

freespace
+12  A: 

You want append a digital signature to your document. This is an area which has been extensively studied. In short, you can with a fair amount of certainty make sure that the file has not been tampered with, but you can't prevent the user from tampering with it.

(The comparison with the music industry is not fully relevant, as they want to prevent people from copying the file as well, which is a much harder problem.)

JesperE
A: 

This is what md5 hashes and CRC's are for, and that's why you check downloaded files from the internet against their md5 file, to be sure it wasn't highjacked en-route.

Anyways I think Roddy uses C++ so I can recommend Boost::CRC its very fast and little overhead, you also don't need to encrypt the file that way

Robert Gould
You're right I use C++. But anyone can generate a new MD5 hash... My problem is preventing someone editing the file, recreating a hash and thereby making the file appear authentic. The digital signature approach seems the way to go.
Roddy
+1  A: 

For your concern about distributing the hash... The good practice is to make the hash and encrypt it with a private-public key pair. And you only have to distribute the public key. That way, they can read it but cannot modify it or create new one.

I suggest to go with Digital Signature as suggested by JesperE. The process is standard, you will find many example demonstrating it.

Hapkido
+3  A: 

Use a digital signature. A signature is a hash encrypted with public-private-key encryption. Your application only contains the public key. This key is used to decrypt the hash and then the hash is verified. To "correct" the hash after a file modification, the user must calculate the new hash, encrypt it with the private key, and replace the old one at the end of the file. Problem: He doesn't have the private key. The private key is not in your app. The private key is not shipped anywhere with your application. Your application has only the public one. If he encrypts it with the public one, it won't decrypt with the public one, so this is useless. The private key is on your computer and nobody has access to it.

Mecki
+1  A: 

Even if users patch their own binaries to ensure that their editted copy of the file works properly, the editted copy of it still won't work on unpatched machines. What is the purpose of preventing this editting?

As an aside, users are less apt to edit binary files than plain text files. Further, users are less apt to feel annoyed if you hand them a binary file than if you hand them a text file with a checksum, assuming they have some legitimate reason to wish to edit it and can, by looking at the file, tell that it would have been easy to do so if you hadn't added a checksum or whatever.

Brian
A: 

Who are your users and how hard are they going to try to change the file. If your users are able to find the salt you are adding to your hash then they can likely find a public key in your code, change it to a public key they generated themselves and calculate the signature on the modified file with their private key. I'd go for obfuscation of the salt.

The alternative is some sort of online system which adds huge levels of complication and is usually crackable anyway.

Have a look at HMACs for a codified method of using a 'salt' as you're thinking (where the salt gets called a key instead).

Patrick