I originally posted this in the security.stackexchange forums but then I was directed to this one which seems more befitting for my question.
I am writing a C# .NET application. For my application the following requirements should be met:
- The data of the users should be stored encrypted in the database
- Users can share data with other users
- I, as the developer, should be unable to decrypt any user data
- If the user resets their password, previously encrypted data should still be possible to decrypt
- The private key should not be stored anywhere on disk. Ideally, I want the client application to be able to derive the private key, for example from the password, every time the user logs in.
I cannot seem to find a solution that meets all five requirements. So far, I have come up with the following cryptographic system using asymmetric encryption: When a user registers, a public-private key pair is derived based on the user password (Is that even possible/practical?). The public key is stored in the database. When the user shares data with another user, it is encrypted with that other user's public key and stored in the database. But now req. 4 is not met, since the key pair is based on the current password a reset will render all previously encrypted data undecryptable.
If instead I use symmetric encryption to encrypt the data, then I can encrypt the encryption key using some password based key, which solves req. 4. However, then I am unable to meet req. 2 i.e. share data with other users. This is, of course, because the user would need the other user's symmetric data encryption key which is encrypted with the private key.
So I am finding myself stuck and unable to come up with a solution that fixes all issues simultaneously.