I've developed a web application (developed in .NET MVC 4) which have multiple users with personal login credentials. The web application holds a lot of content uploaded by the users.

My client would also like to have an offline version of the application, for Windows. This application should use the same information available on the web, it should be available offline, and it should be secured in a way that a user should not be able to take the application content and give it/sell it to a competitor (in an easy way).

So I have in my web application implemented functionality to create an application package, containing all relevant information, which is downloadable and encrypted with a symmetric key. However, each user should be able to decrypt the package with his/hers credentials (i.e. personal passwords).

So when a user is created I create an asymmetric key pair for that user, and the private key is stored in the database as a encrypted string where the key is the private password (stored as a hash from bcrypt).

This list of events means that there's a whole lot of nested encryption and it makes me feel uncomfortable because I don't really know if it's secure enough - so I would like some inputs on my method of choice.

The chain of functionality;

When creating a user;

  1. Create an asymmetric key pair
  2. Encrypt the private key with the users credential password
  3. Hash the password with bcrypt
  4. Store hash + encrypted private key for the user

When creating an application package;

  1. Create a symmetric key [Server side]
  2. Create an application package (raw data) and encrypt it with the symmetric key [Server side]
  3. For each user, encrypt the symmetric key with the users public key and store the result so it can be downloaded [Server side]
  4. A user logs on to download the package+encrypted symmetric key+encrypted private key [Server side]
  5. Decrypt the stored, encrypted, private key with the users credential password [Client side]
  6. Decrypt the stored, encrypted, symmetric key with the now decrypted private key for the user [Client side]
  7. Decrypt the application package (in memory on the clients computer) and show the content via a small, built in, server [Client side]

Is this a fairly secure way to solve my problem? Can I do it in any other way? Is there any obvious security holes in this solution?

migrated from programmers.stackexchange.com Jan 15 '14 at 18:01

This question came from our site for professionals, academics, and students working within the systems development life cycle.


If you want to make it so that the data remains encrypted except for some users, who each have a password, then you have the correct sequence. However, it will help you a lot not to reimplement it from scratch. With a slightly higher point of view:

  • Each user has a keyring containing his private key, and protected by a password.
  • The application data is asymmetrically encrypted with the user's public key.
  • The asymmetric encryption is made so that it is efficient: it is adequate for dozens of megabytes of data, and when the same data is encrypted for several users then the bulk of the data is only stored once.

At that point, you recognize the problem to be what GnuPG solves. GnuPG implements the OpenPGP format which was initially designed for emails, but in fact it can process arbitrary blocks of data. The libraries and tools already include all the hybrid encryption and sharing for multiple recipients, and also password protection of the private key. The format is a reasonably well-studied standard, there are multiple open-source implementations in various languages, this is maintained and mainstream. And you do not have to devote thinking time to the underlying symmetric keys and nested algorithms.

However, the goal might be unreachable. If the data is available, at some point, in the attacker's computer (here, the attacker being the user himself, who wants to extract the data and sell it to competitors), then the attacker will be able to obtain it directly. That's his computer; he can scan the RAM at will.

Of course we can begin to argue about how "easy" it is for the "average" user. But it must be remembered that if there was a secure way to protect the data under these conditions, there would be no music, movie or video game piracy; and even though the individual value of a single song is low, people do extract data from players.

To a large extent, the added value of a GnuPG-based encryption scheme, in your situation, is that it makes it very obvious and undeniable that your intent is to prevent and forbid bulk extraction of data. This can help in legal situations; whoever extracted the data can no longer claim that he did not know it was forbidden.

  • Thank you, good answer! I know that RAM can be accessed and the encrypted contents retrieved without too much effort - and so is my client. I told them this before implementing the solution, and this is an unlikely scenario which they are fine with. I will consider the GnuPG solution, and look into it. – Björn Jan 21 '14 at 23:16

it should be available offline, and it should be secured in a way that a user should not be able to take the application content and give it/sell it to a competitor

This is not in general possible. The user controls his computer, and can bypass any security mechanism if he is motivated to do so. For example he could use a debugger to halt your program and read the keys from memory.

Complete prevention by technical means is not possible, so is the wrong goal. Suitable goals are:

  • Keep honest people honest
  • Provide tamper-evidence/audit trail.

The first can be achieved relatively easily be obfuscating or encrypting local files in some way. However your scheme is over the top. You need only issue each user a unique key (which the app stores) and issue the documents/resources encrypted to that key. Of course they can easily decrypt it if they put in a little effort.

The second needs to be achieved using some sort of watermarking scheme. There are many, but if you are for example supplying the content as PDF files, you can watermark these easily with for example "This copy issued to username@example.com on 2014-01-21" on every page - this will be visible to the user. (In light grey, running up the left hand edge of the page is a popular choice). You might also want to include a second "secret" watermark, to attempt to catch those who go to the lengths of erasing the obvious one.

Watermarking requires you to issue an individual copy to each user. This is not technically difficult of course, but may be inconvenient.

  • I actually don't know what you are trying to say, watermarking? Keeping honest people honest? I asked if my solution, in detail explained, was fairly secure. I know that RAM can be accessed, but getting all the contents out from an encrypted package through a debugger, reading RAM memory, is not a trivial task - and my client is also aware of this risk. I should've mentioned that in the original post, probably. – Björn Jan 21 '14 at 23:12
  • 1
    @Bjorn, the answer is no, it is not secure at all, it is not a "risk" it is a certainty that if the information has any value at all someone will leak it. The solution is law enforcement, which means you need to be able to identify who leaked it, which means you need some sort of watermarking. – Ben Jan 22 '14 at 9:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.