tags:

views:

592

answers:

9

I'd like to bind a configuration file to my executable. I'd like to do this by storing an MD5 hash of the file inside the executable. This should keep anyone but the executable from modifying the file.

Essentially if someone modifies this file outside of the program the program should fail to load it again.

EDIT: The program processes credit card information so being able to change the configuration in any way could be a potential security risk. This software will be distributed to a large number of clients. Ideally client should have a configuration that is tied directly to the executable. This will hopefully keep a hacker from being able to get a fake configuration into place.

The configuration still needs to be editable though so compiling an individual copy for each customer is not an option.

A: 

just make a const string that holds the md5 hash and compile it into your app ... your app can then just refer to this const string when validating the configuration file

Joel Martinez
A: 

It's important that this be dynamic. So that I can tie the hash to the configuration file as the configuration changes.

Mykroft
+8  A: 

A better solution is to store the MD5 in the configuration file. But instead of the MD5 being just of the configuration file, also include some secret "key" value, like a fixed guid, in the MD5.

write(MD5(SecretKey + ConfigFileText));

Then you simply remove that MD5 and rehash the file (including your secret key). If the MD5's are the same, then no-one modified it. This prevents someone from modifying it and re-applying the MD5 since they don't know your secret key.

Keep in mind this is a fairly weak solution (as is the one you are suggesting) as they could easily track into your program to find the key or where the MD5 is stored.

A better solution would be to use a public key system and sign the configuration file. Again that is weak since that would require the private key to be stored on their local machine. Pretty much anything that is contained on their local PC can be bypassed with enough effort.

If you REALLY want to store the information in your executable (which I would discourage) then you can just try appending it at the end of the EXE. That is usually safe. Modifying executable programs is virus like behavior and most operating system security will try to stop you too. If your program is in the Program Files directory, and your configuration file is in the Application Data directory, and the user is logged in as a non-administrator (in XP or Vista), then you will be unable to update the EXE.

Update: I don't care if you are using Asymmetric encryption, RSA or Quantum cryptography, if you are storing your keys on the user's computer (which you must do unless you route it all through a web service) then the user can find your keys, even if it means inspecting the registers on the CPU at run time! You are only buying yourself a moderate level of security, so stick with something that is simple. To prevent modification the solution I suggested is the best. To prevent reading then encrypt it, and if you are storing your key locally then use AES Rijndael.

Update: The FixedGUID / SecretKey could alternatively be generated at install time and stored somewhere "secret" in the registry. Or you could generate it every time you use it from hardware configuration. Then you are getting more complicated. How you want to do this to allow for moderate levels of hardware changes would be to take 6 different signatures, and hash your configuration file 6 times - once with each. Combine each one with a 2nd secret value, like the GUID mentioned above (either global or generated at install). Then when you check you verify each hash separately. As long as they have 3 out of 6 (or whatever your tolerance is) then you accept it. Next time you write it you hash it with the new hardware configuration. This allows them to slowly swap out hardware over time and get a whole new system. . . Maybe that is a weakness. It all comes down to your tolerance. There are variations based on tighter tolerances.

UPDATE: For a Credit Card system you might want to consider some real security. You should retain the services of a security and cryptography consultant. More information needs to be exchanged. They need to analyze your specific needs and risks.

Also, if you want security with .NET you need to first start with a really good .NET obfuscator (just Google it). A .NET assembly is way to easy to disassemble and get at the source code and read all your secrets. Not to sound a like a broken record, but anything that depends on the security of your user's system is fundamentally flawed from the beginning.

Jim McKeeth
Just on a small note, even if written in C++, if you send/store the secret, you are risking it being stolen (This is the key part here). The only surefire way to achive proper security here is to never send the secret. Likely you will need some sort of two part encryption whereby the user and your own private keys are used. As Jim said, you need a proper security analyst and professional advice here.
Gregory
+1  A: 

Out of pure curiosity, what's your reasoning for never wanting to load the file if it's been changed?

Why not just keep all of the configuration information compiled in the executable? Why bother with an external file at all?

Edit

I just read your edit about this being a credit card info program. That poses a very interesting challenge.

I would think, for that level of security, some sort of pretty major encryption would be necessary but I don't know anything about handling that sort of thing in such a way that the cryptographic secrets can't just be extracted from the executable.

Is authenticating against some sort of online source a possibility?

Mark Biek
+1  A: 

Do you need a 100% guarantee that nobody but your program can change the file, or will a let's make it really hard solution work for you?

Lasse V. Karlsen
A: 

@Jim McKeeth the FixedGUID is the same for each copy of the executable isn't it? Is there a way to get a serial number or something similar for each copy of the executable that could then be used in that function?

Mykroft
+1  A: 

I'd suggest you use a Assymmetric Key Encryption to encrypt your configuration file, wherever they are stored, inside the executable or not.

If I remember correctly, RSA is one the variants.

For the explanation of it, see Public-key cryptography on Wikipedia

Store the "reading" key in your executable and keep to yourself the "writing" key. So no one but you can modify the configuration.

This has the advantages of:

  • No-one can modify the configuration unless they have the "writing" key because any modification will corrupt it entirely, even if they know the "reading" key it would takes ages to compute the other key.
  • Modification guarantee.
  • It's not hard - there are plenty of libraries available these days. There're also a lot of key-generation programs that can generate really, really long keys.

Do take some research on how to properly implement them though.

chakrit
A: 

@Chakrit That still doesn't stop someone from getting there hands on a copy of our program and create a configuration that could be placed anywhere and overwrite the configuration. Ideally a given configuration should be tied to a single install.

Mykroft
A: 

@Mykroft Sorry, I'm a little confused. Are you expecting something like obfuscation?

Pretty much anything that is contained on their local PC can be bypassed with enough effort.

Quoting Jim

chakrit