I’m in the process of building a secure document storage on behalf of users of a web and mobile application. The goal is to have end-to-end encryption, as in documents will be encrypted and decrypted on device, but not require users to manage a private key themselves.
The plan is to use libsodium to encrypt documents using a symmetric “content encryption key” (CEK), then using envelope encryption to encrypt that CEK with the public key of the users that should have access to the documents. The main question is then, how to store the private keys. Ideally the private key would never leave the user’s device, but that complicates accessing documents from multiple devices, “digital legacy access”, recovery in case of loss of key etc.
I’m not looking for the absolute perfect system where don’t have to trust any part of the system etc, but something in between that and just HTTPS and “encryption at rest” at our storage provider. I do understand that for us to keep the private key weakens the solution, and this question is about how to mitigate that risk as much as possible.
The current idea is to generate a public/private key pair for each user, store the public key in our database a long with other user info, and store an encrypted version of the private key in a different database (potentially a key storage solution like Azure Key Vault) that will have very strict access control, but accessible by the application server. The encryption key for the private key will be a user defined password (or at least a key derived from that password). That way we keep the private key in our possession, but cannot use it without knowing the users password. We would also need some sort of recovery method in case of a lost password, potentially creating a recovery paper-key that users are told to store safely that we can use to decrypt the private key.
In this suggested solution, the users password would need to be sent over HTTPS to our servers to do the encryption/decryption of the private key, and either the key needs to be transported to the users device, or the decrypted CEK will need to be transported to the users device. With either the private key and the encrypted CEK, or the decrypted CEK on the device, the document itself can be decrypted.
With this system we would never store unencrypted documents, never store encryption keys a long side documents. We have no way without knowing the users passwords or recovery keys to decrypt the documents. Documents are never unencrypted outside the users device.
Is this a secure system, or is all the complexities around encryption useless since we at some point need to send some keys over the “wire” to the user?
All API communication also requires an API token that you cannot get without using a MFA authentication scheme. So the user defined password described above is just for to decrypt the private key. So one needs to both have an access key using the MFA auth scheme + the user defined password.