views:

80

answers:

4

I'm developing an "offline" application for a local government that will be used to collect sensitive information. The application will sync back up to the mothership periodically, but it will generally be used offline.

It'll be running on Windows, written in .NET/WPF. I'll need a small "local" database, so I'm looking at SQLite. I could run something like SQL Express on the PC also, if it gave me worthwhile benefits, but that's a lot of extra setup vs. SQLite.

Looking for input, thoughts, or best-practices on a couple of concerns:

  • Authenticating users to determine who's using the application. I already do this in the "connected" version, but I'm hesitant to store an entire copy of my users table locally.
  • Securing the database to prevent access to or tampering of data should the PC (laptop) be stolen.

Can anybody point me in the right direction?

Thanks! Tim

A: 

You will need to decrypt the database in order to write to it, so the encryption key is going to have to reside locally to the application.

Even with a requirement for a dongle (or something like that), a determined hacker will always be able to find a way through.

Oded
That's an interesting thought though -- what if I stored a secret (like a private key) on a USB key or dongle and used that to encrypt the data? Then an attacker would need both pieces, short of breaking the encryption, correct?
Tim Ridgely
That's the theory ;)
Oded
I suspect a dongle would need to be more than a repository for the private key. Otherwise it's no better than a password the user has to remember. In fact, it's worse, as if someone stole the laptop they'll most likely take the bag which includes the dongle in it! Sure, you can password protect the private key, but that's just applying one password on top of another (which is not two factor authentication).It would be better to ensure the computers hard drive is encrypted. Though I'm the first to admit it's not always the most realistic option when dealing with a customer.
Mike
OK, I'm think I'm starting to figure this out. Not at all sure on the implementation.How about doing two-factor encryption with a password (that the user knows) and a USB private key token (something they have)? So they have to supply both of those things in order to get at the stored data.Also, perhaps the combo could also be used to authenticate the user in question, maybe by storing the corresponding public keys? Given that it's all local, I'm not sure how a trust web could be established to maintain the public key -> user association.Thoughts?
Tim Ridgely
+1  A: 

This is perhaps the best security with consideration for your configuration, but it won't be cheap.

The secret key should be a hash value of a 32 character password hashed with SHA512. A CAC should store the key and should perform the processing of the hash comparison submitted by the client software. The benefit to this solution is that brute forcing will not work if the CAC can be configured to disable its processor after 3 failed attempts and it can store the key securely where tampering or attempts to read the data can also result in a lock state. Each CAC should have a secret key unique to a single respective client application and that secret key must be defined and instantiated prior to the client receiving either the CAC or the software.

Once the software is ready to beam back to the mothership the CAC can process that request as well and encrypt the data using a generic secret key. The key for transport can be generic because you are only encrypting the transportation of the data. The data being transported should remain encrypted with the individualized secret key stored on the CAC.

Once the data has arrived back at the mothership in its encrypted form the data should be manually delivered to a special decryption server not located on any network. This server should contain a table of the individualized secret keys written to the distributed CACs. Once the data is decrypted it must be manually delivered to the central processing server.

This is as secure as encryption allows. Everything after this point is a matter of installation and data secure standard operating procedures back at home station.

+1  A: 

Instead of trying to authenticating the users in your application, simply let windows authenticate them when they login (the do have to log into Windows, correct?). If your application needs to know the identity of the logged in user, you can simply make a function call.

Rather than rolling your own encryption (seldom a good idea), why not simply use Windows encrypting file system? This is available in all versions of Windows from XP on. Take a look at Best practices for the Encrypting File System That way you need to literally make no changes to your application, simply enable the encripting file system.

JonnyBoats
A: 

They key thing to realise here is that while your software is out and under the control of the user, nothing it tells you can be trusted implicitly. If, when it reconnects back, it tells you "The following data was changed by an authorised user", or "The following data was entered by User X", then it needs to cryptographically prove that to you.

One way of implementing this is as follows:

  • The central server maintains a set of all user's public keys in some asymmetric algorithm (eg RSA);
  • The travelling application takes with it a set of all valid users' private keys, each one encrypted ("armored", in the parlance) with a symmetric algorithm using a key derived from the corresponding user's personal password under a good password-based key derivation function;
  • The travelling application prompts the user for their password, which is used to unlock their private key - no unlock, no workee;
  • As the user makes changes in the application, the travelling application records a list of deltas to the database - each one signed with the user's private key;
  • When the travelling application reconnects, the set of database deltas and signatures is uploaded to the central system. The central system checks the signatures (using the user's public key, which it knowns), and rejects any that are invalid;
  • The central system checks each database delta against the relevant access control policy (eg deltas signed by User A should not modify data that only User B is allowed to legitimately change).

You can (and should!) use an existing solution like GPG / PGP to do the cryptographic heavy-lifting (key generation & armoring, signature generation & checking).

caf