I want to design an API-based system that is able to securely encrypt a stream of data received on behalf of an external user in such a way that the data can only be decrypted using a secret that only the user knows (i.e. after encrypting the data, the server itself would not be able to decrypt it again). Naturally, my first thought was to use asymmetric cryptography for this:
- The server would generate a private/public key pair (e.g. using RSA)
- The private key would be securely handed to the user and erased from the server, the public key would be stored on the server.
- When new data arrives for the user, the server would generate a random key for a symmetric encryption scheme (e.g. AES) and use this key to encrypt the data. It would then use the users public key to encrypt the symmetric key and store it together with the data on the server.
- The user could then decrypt the data by downloading the encrypted data with the corresponding encrypted symmetric keys, decrypting the symmetric keys using his/her private key and finally decrypting the data using the decrypted symmetric keys.
The main challenge is that the data which is received on behalf of the user consists of many small packages that arrive continuously over time. In order to encrypt them following this scheme it would thus be necessary to generate and encrypt a new symmetric key each time a new data package arrives, which is doable. However, the decryption of the data could become very inefficient, as the decryption of an RSA-2048 encrypted message can take several milliseconds on modern hardware, so if there are many thousands or even millions of messages for a single user, their decryption could take hours.
I therefore have two questions:
- Is this a reasonable scheme? If now, which elements are missing or would be advisable to implement in addition (HMAC, signing, ...)?
- Is there any way to increase the efficiency of the decryption process, preferably one that does not involve storing the symmetric key on the server over an extended period (which would be a security risk)?
The user does not upload the data, it is generated by a third-party on behalf of the user. The motivation behind the scheme is to provide the third party with a secure, asynchronous channel to store data that a user could securely pick up at a later point in time. The assumption is that the third party is not able or willing to provide the infrastructure for this by themselves and instead want to use an external service.