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.
It's important that this be dynamic. So that I can tie the hash to the configuration file as the configuration changes.
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.
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?
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.
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
Related
I want to do the below. What is the best way to achieve this?
I have a desktop app in C# which will be installed on multiple client machines.
The application is capable of doing an operation X but it needs some auxillary info which it can read from a file. This auxiliary info essentially provides some specifics that identify that machine where the operation should be run and what operation to run etc.
I will work with the client to get some of this auxilary info about his machine (say hostname/ip address etc) which I want to put in this file along with other info and generate it on my machine and share it with him/her to provide it to my software. I want to encrypt this data so that the structure of the data is not obvious to somebody who opens it. (I will get some of the machine identification info from the client, either via phone or email).
I want to somehow encrypt and secure this file such that only I can generate the file but any of my installations can read it. But since the contained info is specific to a machine it will be executed only on one machine (other machines will read but reject it since the given hostname/ip etc won't match that machine)
How do I do this? I want to make sure the below:
Only I can generate this file.
I need to somehow authenticate that this is generated only by me and not by somebody else.
But my software on client machines should be able to decrypt this.
I don't want to take a password from the customer etc. all the decryption logic should be in the installed software itself. I want to code it in.
When I researched this online, many talk about public and private cryptography but there they talk about encrypting with the public key and decrypting with the private key. But I don't think this will work since decryption is being done by my software at the client machine and so I shouldn't put the private key in my code. Because, from what I read, private key can generate public key so somebody could potentially generate that instruction file if I do this.
What is the best way to do this? Can I encrypt with private key and decrypt with public key? Is it ok if somebody gets hold of my public key (say they disassemble the C# code)? Any other good ways to encrypt and authenticate such that I hold the private data with me but code only harmless public keys/data in the application?
TIA.
Who are you trying to protect this from?
You are giving the end user your application binary. Assume they can decompile it and work out how it works. Or step through your code in a debugger, with access to the contents of every variable. Assume that an attacker can learn everything they need to know about how it works.
At best I would recommend creating a hash of the machine details and a salt value. Then create a signature of that hash.
Keep the salt and the public key of the signature as a constant in the application binary. Maybe XOR values together so an attacker has to think a little about how it works.
But anything more is pointless. Any attacker with more skills will just patch your program to delete the test entirely. So I wouldn't bother building anything too complicated.
Giving someone a program, and preventing them from using it, is like trying to make water not wet.
You have two questions
How do you encrypt the information, and
How can your client make sure the information came from you.
Those are orthogonal
I'll address the second on first - it's easier.
First, hash the file, and add the hash to the payload. Then generate a public/private key pair, then encrypt some known (but non-trivial) information with the private key and add that to the payload. You can distribute the public key with your app. If your app hashes the file and the hashes match and it can decrypt the known information and make sense of it, then it came from you and no one has changed it.
This is known as a digital signature. If you look up a digital signature provider and follow the docs, it should just work.
The encryption problem is more of an issue. There's pretty much no way to do what you want. If your app can decrypt the information using information you distribute with the application, then a determined bad guy can extract that key material and decrypt it.
However, you can use the RSA key container on the client to do the encryption when you install the app. The process is similar to using encrypted sections in a web.config file. Since you won't be following the encrypted config section cookbook the process is complicated.
I've done this before, but it was several jobs ago, so I don't have anything I can show you.
But, it will be encrypted so that it can be read only where it was encrypted. No two installations will recognize each others files.
That said...
Encryption seems like a heavy hammer to prevent your customers from being able to guess "the structure of the data [so that it] is not obvious to somebody who opens it"
Unless you have something worth protecting, you can probably get away with obfuscating the data. For example, you could have the data as JSON, but then use GetBytes on a Utf8Encoding to get a byte[] and convert that to a hex string. A determined hacker could decompile you code, figure out what you've done and reverse it, but that doesn't seem like a threat you really need to worry about.
I have Created a C# Desktop Windows form Application and I have created a setup for that. In the C:\Programs files app folder I have a JSON file. I need to protect it from accessing by anyone (I need to protect the data). What should I do?
You can't. If the intruder have access to the computer with the Administrator rights (or even more - a physical access to the hardware), then any protection will be useless.
You can use some kind of encryption, code obfuscation and some anti-debugging techniques to make it harder to retrieve the data, but qualified intruder with the appropriate access level will be able to access the data in the moment when you will decrypt it.
The only working way is to completely remove the secret data from the client's computer and move it to the your secure server alongside with the processing of such a data. So, client sends the inputs to your server, the server performs the processing using the secret data and sends back ready-to-use results.
First of all: it's impossible to make it un-breakable - I won't argue on this. Then you can simply encrypt it with a simple Blowfish algorithm and keep the key hardcoded.
You can use a more secure algorithm if you want so.
Easiest solution is to use a binary serialization format instead of json. This will make it much harder to understand and decode. Or just hardcode the data instead. Most people lack the knowledge to do anything meaningfull with a binary chunk of data, or an assembly for that matter.
A more complicated solution would be to sign the data, as this would allow you to only hardcode the key. A related alternative is Encryption. Encryption is sufficient but not necessary for ensuring the integrity of the data, but is not really more difficult to apply, see encrypting data.
Whatever you do you cannot really prevent a sufficiently determined and knowledgeable attacker. It is possible to decompile the program and extract or replace any secrets therein. The only truly secure way would be to prevent access to the files in the first place, by moving it to the web for example.
I had a similar requirement and decided to encrypt the data.
I used the package "AuthenticatedEncryption" (available from NuGet ) and could hard-code the key in my code.
NuGet: https://www.nuget.org/packages/AuthenticatedEncryption/
Guthub: https://github.com/trustpilot/nuget-authenticated-encryption
I can do this, as my main purpose is more to make the data unreadable to users and I don't expect it to be unbreakable.
Even so, I change the key every few releases.
For my ~70Kb JSON file I only load it once at the start of the program, so performance is not a problem. Not that I anyway notice anything!
I'm working on a project that is going to replace legacy software on our manufacturing floor. One of my concerns is that currently, config files, script caches, etc are all plain text, stored on the system that the user is using. A lot of this stuff is going to get pushed off to limit access network locations, but things like config files stay local. It's already been an issue with users thinking that they know what they're doing with the system, and modifying the config files. I don't want this happening any more in the new software. How should I prevent this? Encryption? Do some sort of signing/checksum with a database lookup? What kind of features does C#/.NET offer to help me out with this?
UPDATE: Just to address some things that were brought up in comments, every user on the manufacturing floor has admin access to the system they're working on. This isn't likely to change soon as most of the security comes from limiting access to folders on the network, web services, and databases. Permissions would be ideal, I agree, but I have to work in the environment that I'm provided. I plan to bring it up in a meeting that I have with IS to see if this is a possibility, but assume for now that this will be on a system where the user has full access.
This isn't a C# coding issue, it's a system configuration issue. Set up the machine such that the users have normal (non-admin) accounts. Set the file permissions on the config files you're worried about so that anyone (including your app running as current user) can read the config files, but only an admin can write the config files. Finally, don't give the users the admin password. ;>
If your app needs to be able to write the the config files also, you'll have to add code to transition into admin mode within your app, preferably only around the write operation.
To prevent the average end-user from modifying config files by hand, you could simply sign the config file using the SHA of its contents concatenated with some secret factor known only by the program. This is obviously not a true or perfect secret, but it's enough to prevent simple tampering by end-users.
Basically (pseudo-code):
function isValidConfig(configPath, signaturePath) {
return readFile(signaturePath) == SHA(readFile(configPath) + secret)
}
function writeConfig(contents, configPath, signaturePath) {
writeFile(configPath, contents)
writeFile(signaturePath, SHA(contents + secret))
}
Short of decompiling the program, they won't be able to tamper with the config. I assume you don't have l33t crax0rs on your manufacturing floor...
This seems like a good job for a Digital Signature. A Digital signature will provide integrity and authentication of your data. Meaning the digital signature will detect if the data (config file) has been changed, and that the data originated from a trusted source. A digital signature is created by performing a hash of the data and then encrypting the hash with a private key from a public/private pair. The Application will decrypt the encrypted hash, calculate hash of the data, and compare the decrypted hash to the calculated hash. If the hashes match the data is valid. If they do not match the data has been altered.
.Net contains these functions in DSACryptoServiceProvider.VerifyHash
Of course if you do not want to go through the hassle of creating a public/private key pair you could just go with a simple hash of the config file to make sure it hasn't been altered.
The really important question is; what are you going to do when the application detects an altered config file?
Are you going to have the application quit, lock out certain functions, send an e-mail to you, try to obtain a good copy of a config file? These actions are referred to as the penalty for failing the integrity check. Right now your application is not performing integrity checks on the config file, but when you add the check you will need to decide the best course of action for a failure.
An option is for you to move as much as you can from the config file to either IsolatedStorage or even better to the database. It would be highly unlikely that a typical user would know how to access them.
I'd keep the files in some kind of structured storage, be it isolated storage, slightly encrypted ZIP file or something like our SolFS virtual file system (also encrypted). The secondary benefit of having one file is that it can be copied for backup easily.
I'm not an expert in local security but maybe you could use file system permissions to prevent use access to a given folder or file.
Then, if you application needs to access this file, you will have to launch your application with different windows account that has the right to modify your file.
We have around 60 MB of device configuration implemented in at least 1000 xml files.
Now we are releasing the software to the customers. But our requirement is not to allow the user to view and edit the xml configuration files. XML configuration files contains a lot of secret of the device information which can be easily hacked if it is readable.
Now we need to encrypt the xml files. Are there any recommended method to encrypt the xml file and it can be decrypted at run time?
This is a problem known from DRM applications - you want to make the data available to the user agent of your choice but not to the user operating the user agent. But, since the user agent is usually on the user's side, as Jon and Oded point out, a determined hacker will find a way to break the encryption. It's a cat and mouse game. You are trying to find a solution to exactly the same problem that people implementing DRM want to solve. Software-only user agents are easier to hack than hardware-assisted user agents, but in either case time works for the hackers. The latest development is the latter - embedding all the cryptography in hardware - like the HDMI's HDCP method (High-bandwith Digital Content protection Path) where they have essentially made the decrypted digital signal inaccessible to the user by letting it pass along black-box hardware from its point of decryption until it is made so available, but at the intended destination - TV screen. The key for HDCP to succeed however was implementing it in hardware. Most hackers have learned to deal with software. But since I would say there is 1 good hardware hacker per 100 good software hackers these days, the mouse hopes no cat will be around to catch it. Sorry for too much theory, it is essential to your problem though, I believe. If you are still willing to play the game, encrypt your XML files and make sure the decryption key is not available to potential hackers on a silver plate - i.e. obfuscate it, can't do much else.
How determined are you expecting the "hackers" to be? If all the information required to decrypt the information has to be present on the system anyway, then a determined attacker is going to be able to get at it anyway.
You can use the classes in the Cryptography namespace.
Most of the encryption classes will allow you to encrypt and decrypt streams, so are good for your purpose.
However, you will still need to hold the encryption keys somewhere, even if it is in the assembly.
As Jon points out, a determined hacker will find a way to break any encryption.
As others explained, you won't get it absolutely secure without a trusted device which stores the key and does the decryption without granting access to the key under any circumstances. Computers aren't "trusted devices"...
My employer sells such technology and if your data is really money worth, you should possibly take such a solution into account.
If an additional USB-Dongle is not acceptable (or too expensive) at least use public-key (asymmetic) cryptography (see System.Security.Cryptography).
Asymmetric cryptography has the advantage that the key used to decrypt your data can't be used to encrypt the data.
Your application has to store the decryption key and the hacker can determine it with more or less effort. He then can decrypt all your data but he can't not encrpyt the changed data again. So he can't use your application with the changed data.
If you want to prevent him from doing this, you have to obfuscate your application and use anti-debugging techniques (static and runtime). If you go this way buying an existing solution is probably cheaper.
Watch out: Hackers can see all functions in .net generated executables and dll's!
If you make a decription algorithm in your .net project like DecryptXML(string Path), it is very easy for a hacker to call this instruction. So be sure to dotfuscate your project.
I'm developing an intranet application (C#) that uses some data (local to the web server) that we'd like to keep private. This data is encrypted (AES) using a legacy data repository. We can't totally prevent physical access to the machine.
Clearly, we're never going to have perfect security here. However, we want to make it as hard as possible for anyone to gain unauthorized access to the data.
The question is how best to store the key. Encrypting it based on some machine specific ID is an option, but that information would be readily available to anyone running a diagnostic tool on the machine.
Encoding it in the application is an option (it's a one off application). However, .NET assemblies are pretty easy to decompile. So, would it be best to obfuscate it, use an encryption launcher, compile it?
Or is there an option I'm missing?
Just so we're clear, I know it's pretty much a lost cause if someone is determined, but we're looking to make it as hard as possible within the constraints.
Encryption is built into the .NET configuration system. You can encrypt chunks of your app/web.config file, including where you store your private key.
http://www.dotnetprofessional.com/blog/post/2008/03/03/Encrypt-sections-of-WebConfig-or-AppConfig.aspx
Speaking in obfuscation terminology, what you are after is called constant hiding, i.e. a means by which you transform a constant into, say, a number of functions and calculations that are executed at runtime to re-materialize said constant.
This still falls within the domain of obfuscation, however, and is susceptible to either code extraction, where the attacker simply maps out the code relevant to this constant, and runs it in a separate application to retrieve the value; or dumping the application's memory at the right point in order to scan it for the desired value.
There is another, slightly more advanced method of hiding crypto keys in particular, called White-box cryptography, which employs key-less ciphers through essentially generating a cipher function from a given key, baking them together. As the name suggests, this method has been devised to be resilient even in a white-box attack scenario (the attacker has access to the bytecode and is able to inspect and manipulate the executable at runtime).
These are both quite advanced methods of achieving security through obscurity, and it might be worth considering alternative models which do not force you to do this in the first place.
If somebody can just attach a debugger to your program, there is absolutely nothing you can do. They won't have to figure out your config, disassemble your app, etc. All they have to do is run the app - watch it use the key - bingo.
Obfuscation is of no help under those conditions.
The best defense is to use hardware to protect the key - which will do the crypto but not give out the key itself (and is sometimes hardened against attacks such as probing the wires, exposing the memory to low temperatures/radiation/other novel stuff). IBM do some appropriate stuff (google IBM-4764) but it's not cheap.