Pregunta

I have a C# program (could be any programming language) that saves data to a file on a memory (hard disk, USB drive, etc.). The program uses this data for monitoring its operation time, but it could be any purpose.
When the program is started, it reads the data from the file so it knows how long it has been operating before. It updates the data in the file every minute, so there is a failure of maximum 1 minute if the program is not shut down properly.

My problem is a quite general question: How can I prevent the user from manipulating the file?

I want to avoid that someone edits the operation time while the program is not running, or at least I want to be able to detect manipulation.

  • I though of a checksum first, but I also need to prevent that from manipulation.
  • The user can replace the current files by backups every time, thus the files themselves are not save if he knows where to look.
  • Therefore I need to store data at a location that is not easily editable. On a windows system, this could be the registry. Alternatively I could create a hidden system file in a special directory. However, I think the only chance is to hide the file or any information about the data from the user.
  • The user could replace the whole operating system including all data by an image. Therefore also a hidden location is not safe, but a) I cannot avoid this risk, and b) the user would need special equipment and knowledge, so the system is safe to most users.

Any other ideas how to secure data on a typical computer?

¿Fue útil?

Solución

I would suggest the following implementation.

If the program is initially started create an encrypted and authenticated file containing either a timestamp or counter to have a starting value. It is important not to use the basic user displayed and changeable time/clock, because otherwise your customer could just set the system time into the past. When you run the program start a timer or increment the counter to measure the usage and update the encrypted an authenticated file periodically.

The location where the file is stored is unimportant, but you need to use the following things to accomplish reasonable security:

  • Use existing cryptographic functions, which are well tested and provide both encryption and authentication. To put it simple, encryption protects you from somebody trying to figure out the content, authentication from manipulation

  • Generate a random key for the encryption, no hard coding. Everything that is hard coded can be found through reverse engineering with more or less effort. Also reusing keys is always a bad idea

  • Store the key some place save where it can be automatically accessed by your program. This is the tricky part, as you have to trust the OS to properly handle it, as things need to be working without you entering things manually. My suggestion would be using DPAPI (assuming you develop for C# .NET on Windows). You can easily store your key, and could as well be changing your key once in a while without big hassle.

So if the user either deletes, exchanges the file with an old version or manipulates the file, you are able to recognize it.

I hope this give some ideas how you could do it.

Edit

I was not correct regarding the replay attack, if the user is able to access both files then indeed he would be able to replace both with old versions.

My suggestion regarding your comment would be the following:
Have a file that contains a timestamp, the counter for usage, shutdown flag.

You will need a windows service running on start-up. Set a registry entry on the very first start-up.

The service checks for if the file is existent and if it is the very first time the service runs. If there is registry entry says that it runs for the first time, create the file containing the current timestamp (non-dependend on system clock, if possible), the counter for usage should be zero and shutdown flag false. The file is encrypted and the key encrypted through the DPAPI (use a fixed additional entropy). The registry entry is updated as from now on, all consecutive writes will be updates.

Now the service needs to update the file in a fixed interval, e.g. every 10 minutes. This means unprotecting the key with DPAPI and decrypting the file. Here is where we protect against replay attacks. The timestamp in the file is check and may not deviate more than e.g. 30 minutes (should be more than the update interval in case of failed update). If it does deviate more, manipulation is suspected (or heavy error from the application or hardware or OS). Otherwise, if everything is fine, the timestamp gets updated to the current time. If your service/program was used in the meantime, the usage counter gets updated as well. Generate a new key, encrypt the file and store the key after protecting it with the DPAPI.

When the user shutsdown the computer and starts it later on, you would have the problem, that the timestamp exceeds the allowed limit. That is why the file should contain the shutdown flag. This flag should be set when the user shutsdown the computers. When the service is stopped, it's final action is to update the file, with the shutdown flag set to true. On a start-up the file is read and if the shutdown flag is true, set it to false and update the timestamp again.

This is how I would do it. It isn't bullet proof but more than enough to protect against fraudulent customers. I wouldn't even go that far and simply use the DPAPI and file combination and store the output of DPAPI in the registry. No normal person is his right mind would spend his time searching the entire registry. After all they are your customers not prisoners. With physical access to the computer there is no way to absolutely secure it.

The Isolated Storage is not very useful either, I just have read about it the first time. The user and also other programs with administrator/system privileges will be able to read these files.

Otros consejos

"secure data on a typical computer". From your comments it's clear your victims are not using "typical computers" but are slaves to an irrational IT department which you're a part of.

The only way to do what you want is not to store the data on the computer at all, but to store it on another computer somewhere on the network that your users have no access to. Of course that requires that all their computers are networked to a LAN, but you're going to have that anyway as no doubt you've found out that network admins can remotely start, shut down, and reboot computers and forcibly load and remove software on them and are regularly pestering your victims with that just to annoy them as well as for legitimate reasons (yes, I've worked in companies with such IT departments more than I care to remember, I have experienced it from both sides, though I've never been one of those admins I've worked in the same departments they were part of).

Licenciado bajo: CC-BY-SA con atribución
scroll top