1

Short background

I am currently in the process of designing a web-application where the user uploads some files to the server and then asks the server to do some calculations based on these files (task may be queued if the current workload is high). Then the server stores the result and makes it available for the user to view.

These files may contain private and/or sensitive data and therefore I decided to look into ways to keep these files secure on the server side.

I have done some research into this topic but not found the solution that I am looking for. I do have a general idea for the design, but I feel it is flawed and that I might be reinventing the wheel (lacking experience in this field).

I will start with the basic requirements, then present my idea and end with the questions i have.

Security requirements

  • System must encrypt the files before storing on the file system
  • System administrators etc must not be able to decrypt the files on their own (next requirement takes priority over this requirement)
  • System must be able to decrypt the files only if user provides authentication
  • System must support multiple simultaneous users with each user able to only authenticate decryption the files uploaded by that user.

Current idea

Storing the files in a way that decryption is possible only for the user seems quite straight forward. Currently I am thinking of the following workflow:

  1. User creates a public/private key pair (with some 3rd party tools)
  2. User uploads the public key to the system
  3. User uploads file (file stays in memory for now)
  4. System generates shared key for encrypting the file
  5. System encrypts the file with the shared key
  6. System stores the file
  7. System encrypts the shared key with the public key
  8. System stores the encrypted shared key

I believe this approach is quite common and does not have any serious draw-backs.

Now the problematic part. Since I want the user to be able to allow the system to decrypt the file in some situations then this is the only workflow I came up with:

  1. User starts a task that requires an encrypted file
  2. User uploads the private key (stays only in memory)
  3. System decrypts the shared key (stays only in memory)
  4. System deletes the private key from memory
  5. System decrypts the file into memory
  6. System deletes the decrypted shared key from memory
  7. System completes the task
  8. System deletes the decrypted file from memory
  9. System stores the task result

Questions

While I do believe that this approach would be functional, I am still worried about a couple of things:

  • I am not sure if uploading a private key as a regular file can even be considered as a viable option? - If i'm not mistaken, then this at least goes against the usual norms.
  • Can the private key be transferred securely over the internet? - I am inclined to believe that it can, however I have not jet looked into how exactly.
  • Even if the encrypted file (or the private key) is only held in memory for the minimum time needed, would it still be a security risk? - I feel that it is still a risk, but not a serious one.
  • Is this already a solved problem? - If so than I was unable to find the solutions

As a final remark I would like to add that I am fully aware that any such system would require trust from the users. Mainly I would like to know if this is achievable at all, is my idea viable and is there a better/alternative way?

  • You cannot protect against rogue sysadmins. For example, they can modify the JavaScript on your site to avoid encryption altogether. – Neil Smithline Jan 15 '16 at 5:37
  • @Neil Smithline , yes if the sysadmin (or the developer) is able to modify the applications code and the application is able to decrypt the data at some point (latter of which i need), then the sysadmin can circumvent the security scheme. I am aware of that and this is the reason for my last remark. – FableBlaze Jan 15 '16 at 11:00
  • @NeilSmithline Although i think that JavaScript will be an issue only in the upload steps (either stealing the decrypted data or the decrypted shared key). Bypassng encryption via JavaScript entirely does not seem possible, if security is implemented on lower levels of the application. Or am i missing something? – FableBlaze Jan 15 '16 at 11:19
  • If this is a web app, what "lower level of the application" are you referring to? Code running on the server? An admin can modify that if they want. – Neil Smithline Jan 15 '16 at 18:34
  • @NeilSmithline yes, i am aware of that and mentioned it in the previous comments. This risk can be mitigated somewhat, but not eliminated. – FableBlaze Jan 15 '16 at 19:26
1

For part two, you can do sensibly better:

  1. (The session between User and System is encrypted)
  2. User starts a task that requires an encrypted file
  3. System sends tne encrypted shared key
  4. User locally decrypts the shared key
  5. User sends the decrypted shared key (stays only in memory)
  6. System decrypts the file into memory
  7. System deletes the decrypted shared key from memory
  8. System completes the task
  9. System deletes the decrypted file from memory
  10. System stores the task result

You should ensure the memory of the routine that performs the task is not accessible by other threads on the system's service, if you happen to serve multiple clients on the same system, using compartmentalisation techniques like COWL (not sure about its implementation status) or maybe Capsicum.

I'm thinking strongly of secure multi-party computation and homomorphic encryption when reading your problem. I'm not expert so won't dwell on this, though. There might be ways, depending on what you need to compute, to perform the computation without actually having to decrypt the files. This might also be achieved by having clients compute and upload encrypted properties about the files rather than the files themselves.

There are quite possibly tons of other designs, and hopefully someone will point out a better approach.

  • The system will need to support multiple clients simultaneously, I will add this to the question. Secure multi-party computation is unlikely to help me as the tasks are expected the take a long time and be computationally heavy, additionally i would like to have the possibility to keep task processing asynchronous with respect to the client. Homomorphic encryption however seems to be usable at first glance, but i would not go into details a bout it in the scope of this question. – FableBlaze Jan 14 '16 at 23:38
  • 1
    Homomorphic encryption would be a solution if it worked - it's currently not nowhere close practical for any reasonable definition of "use the files" if by "files" you mean many megabytes instead of a few hundred bytes, by "use" you mean arbitrary applications instead of a particular carefully selected small function, and you want each operation to complete in seconds, not hours. – Peteris Jan 15 '16 at 21:23
  • @Peteris yup, I assume if this solution were retained that a lot of pre-computation would need to happen client-side and the result of these computations encrypted for aggregation. It's not likely to be functional for most purposes though, I got to agree with you on that. – Steve Dodier-Lazaro Jan 15 '16 at 23:17
  • @Peteris The files could easily reach into megabytes and are most likely to contain data in XML format. I have not had the time to look into Homomorphic encryption any further, but i'm guessing the XML format would make things even harder. I will leave this type of encryption out of the scope of the application for now. – FableBlaze Jan 18 '16 at 0:47
  • 1
    @FableBlaze most likely yes. Basically you can do really stupid stuff like additions, binary votes, maybe (maybe!) sums or multiplications on single values, but not much more, so you'd have to pre-process. Megabytes of data is definitely not an option. – Steve Dodier-Lazaro Jan 18 '16 at 15:43
1

Don't upload the private key to the server.

Instead, send the encrypted shared key to the user. The user can then decrypt with the private key, which stays on the user's system.

Then, the user sends the decrypted shared key to the server.

  • It does increase the work that the user has to do, but i think it will be acceptable and far more secure. – FableBlaze Jan 14 '16 at 23:30

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.