3

I'm rather new at programming so I'm still getting a grip on things.

I'm creating an offline login system in C# that will have the ability add/remove users. The computer will not be connected to the internet.

This was the approach that I was going to take:

Have the username and a salted + hashed password in an XML file. The XML file will be encrypted with a unique key that is worn around the user's neck (something like an ID card).

So the process should goes like this:

  1. User scans their ID card and enters their username.
  2. Application finds user's encrypted XML file and decrypts it.
  3. User enters their password in.
  4. Application checks it and grants/denies access.

EDIT: To everyone reading, don't do this - It's a bad idea. The assembly can be reverse engineered.

3
  • 5
    "I'm rather new at programming so I'm still getting a grip on things." do not attempt to write your own security
    – Ewan
    Jan 22, 2019 at 11:28
  • @Ewan makes a great point, probably the single worst thing you can do if you need something to be secure, is to do it yourself. This goes for anyone who does not specialise in creating secure systems, not just beginners
    – J Lewis
    Jan 22, 2019 at 15:08
  • @Ewan and JLewis. Thank you for your advice. I will leave the security to the experts.
    – user326468
    Jan 23, 2019 at 6:46

3 Answers 3

4

What's stopping a determined individual from creating their own XML file with their own details, encrypting it with their own key, and placing it on the computer via USB drive?

Before you consider what is (not) stopping them, first ask yourself why they would want to do it to begin with. What do they have to gain by getting a succesful login?

Because if you're using user accounts solely so users can e.g. pick their background color, there's little reason to password protect that, and even less reason to go through the effort to gain illicit access to that information.

If, however, you are handling access to highly private information which should not be shown to unauthorized users, then you really shouldn't be handling local storage on a machine where users have full access. For authorization, you should always rely on a server you manage yourself, which the users have no access through other than the means you've opened to them (e.g. an API).

You can encrypt your entire database as well; but it's always possible to reverse engineer a built application and thus figure out the process of decrypting the database.

When referring to gaming, you can't really cheat in a singleplayer game. If you decide to tweak your game experience without ruining anyone else's (since you're the only player), then what's the harm?

Similarly, I find it very weird that you are giving all your application files and database files to a user, but then worry about them handling the files you've put them in charge of? It doesn't make sense to me, what would be in that database that the user didn't put in themselves? Are you sharing files with private information when you deploy your application and then hoping that no one reverse engineers them?

3
  • Hi, thanks for replying. My app will store reasonably private information; multiple users will have access to it. I do not want unauthorised users getting access. I will rethink my approach and come back some other day. People copying the app and the local database on a USB drive and taking it away to be reverse engineered will also be a problem - Thanks for pointing that out, I will need to think on that. Could you tell me a bit more about your server suggestion? Will it work on an isolated computer with no internet? (I've never really played around with servers before). Thanks
    – user326468
    Jan 22, 2019 at 11:20
  • @Harry: It doesn't need to be via the network. Any form of access management can prevent users from taking actions you don't want them to. Whether that's local user rights management or controlled access to a web server is irrelevant.
    – Flater
    Jan 22, 2019 at 11:22
  • 1
    @Harry - A common way to do "restricted" access on single machines is to start up an OS-provided service with its own user-account, that the individual users talk to through some API and/or inter-process calls. So your application has its own datastore, and the users get direct read/write access to none of it. Of particular note, the authorization database must be managed by the standalone process, not the "user carried" process (which is strange on the face of it, too). Jan 22, 2019 at 22:01
1

Here's where my idea falls flat

Only there? Why would the user fiddle with your attempt at security, when they could just decompile your .NET assembly, add a line in your check function that says if( user.Name == "me" ) return true;, compile it again and run that executable instead of yours?

Repeat after me:

The client is in the hands of the enemy.

The client is in the hands of the enemy.

The client is in the hands of the enemy.

Your program on a computer your user has access to will never be secure. Never.

Your server needs to be separated from that part of the program your user has access to. That could be achieved by a web front-end, or a separate C# program that only communicates user input and program output to and from the backend, a backend your users have no access to except for your API. But a local assembly is never secure.


As an alternate solution: let your users worry about security. Let your program read and write a file with their data to a destination they pick. If they put it in their home folder, whoever controls your network infrastructure should make sure it's safe. If they save it to C:\ that's their problem, same as with any other file.

0

If you are worried about users altering files simply hash the contents of the file. Since XML is string based, one can hash the entire file and then store the hash in the file itself or in another location.

If the user changes the XML file, the hash will not match and they have tampered with the file.

This also works for content as well. If a user alters an image or PDF, then it is not shown. All content and hashes are stored centrally. When the user downloads the file, the hash is checked after the download to make sure the file was downloaded correctly and also every time the file is accessed to make sure the user is not fiddling with content after they have downloaded it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.