How to store private encrypted user data in the database, but make them available to other chosen users?

12,614

This can be solved using public-key cryptography:

  1. Generate a public/private key pair for each user; and only ever decrypt the private key temporarily with the user's password.
  2. For each data item, randomly choose a (symmetric) key S and encrypt the data d with it. Store S(d).
  3. Encrypt S with the the public key P+u of the user you want to grant access. Initially, that's the user u whose data you're storing.
  4. Store P+u(S) permanently. Forget all other keys.

Now, when a user u wants to share the data with the user x, do the following:

  1. Decrypt the user's private key P-u with the user's password.
  2. Using that private key, decrypt the stored data: P-u(P+u(S)) = S.
  3. Encrypt S with the public key of the user you want to share the information with.
  4. Store the resulting P+x(S) permanently. Forget all other keys.

Now, when any user x wants to access the data, perform the following process:

  1. Decrypt the user's private key P-x with the user's password.
  2. Find P+x(S). (If it's not stored, that means nobody shared the data with the poor user x).
  3. Using the private key, decrypt the stored data: P-x(P+x(S)) = S.
  4. Using S, decrypt the stored encrypted S(d): S(S(d)) = d.
Share:
12,614

Related videos on Youtube

Frodik
Author by

Frodik

My favourite programming languages: PHP5, Javascript, jQuery SOreadytohelp

Updated on June 04, 2022

Comments

  • Frodik
    Frodik almost 2 years

    firstly, I apologize if my question sounds little confusing, I will try my best to describe my scenario as detailed as possible:

    I have website where user can input their personal data about themselves. They are mainly health data, so it's very private and sensitive information. So I need to encrypt this data on the server even then the server is compromised these data are secured because they will be encrypted with each user's password. Of course, user passwords will not be stored as clear-type text on the server, only password hashes.

    But my problem is that the website will offer "social function" when user can choose to share some of his/her information with another user. But this would be problem, because I will not have any way of decrypting user private data and so I can't show it to another user.

    Can you please give me some options, or at least ideas, how could this be solved ? Preferrably using LAMP environment.

  • Frodik
    Frodik over 12 years
    Thanks for great solution. I had to read it 5 times to fully digest it, but this is exactly what I was looking for, thank you.
  • phihag
    phihag over 12 years
    @Frodik The linked openssl module contains a list of functions, and each function's signature is documented. I'm sorry, but since I tend to forgo tutorials, I don't know any. However, stackoverflow does.
  • Frodik
    Frodik over 12 years
    I follow-up question. If the user forgets/looses password, all his/her data are forever gone and there is no way how to recover them, right ? I am just thinking about implementing some kind of "Lost password?" feature, where user would get new password sent to his registered email address. Howevere, I quite don't see any way I could accomplish this...
  • phihag
    phihag over 12 years
    @Frodik Iff there is any way to access the information without authentication, an attacker will be able to access it as well when he has compromised the server. What you can do is to have a separate machine which stores the user's private keys in plain and gives them out when the user enters her password, or someone is authenticated by "forgot password" functionality. Equivalently, you can just store the plain-text passwords on another machine, and give them out (or use them to change the password the private key is encrypted with) in that case.
  • phihag
    phihag over 12 years
    @Frodik Unfortunately, every solution will compromise the strict security requirements. There is no way around it. You can't lock away your cake and eat it too.
  • Ravinder Payal
    Ravinder Payal about 8 years
    but according to you the plain-text password is required to decrypt the data which implies either user re-enter password for every page load or the password is stored in some variable dedicatee at client machine or server machine (flow#1) . Now you say you can store passwords as plain keys in another machine then you need to provide some short of credentials or API for accessing that server from the main server , now case the main server is compromised than with help of that the dedicated server can be also compromised.