I want to implement the following encryption scheme. The data is created and stored on a web server, but related to some user of the system (i.e. it is entered "on behalf" of the user). Both encryption and decryption process should involve a request to a mobile device of this user (the encryption password is located on the device). The point is that nobody, including the server, would be able to approve the encrypted data entry on behalf of the user or later decrypt it without having access to a mobile device of the user.
However, we can’t send the whole data to the device for encryption, because (aside from the matters of security) it could be very large. Also, the decryption is done to provide access to some third party, so there's no need to transfer the data to the device at all. So both encryption and decryption should occur on the server.
Another point is that the encryption/decryption occurs on a per-record basis, so it would be preferable that noone (even the server) at any point in time would be able to decrypt all user data at once.
I need to come up with a protocol or a pattern to do this.
As a precondition, the server already has an ID of the user’s device. This allows the server to send a push notification to the device. The push notification channel is secure in the sense that it is over TLS. However, there is a risk that the messages are stored as plaintext somewhere in the push notification provider database and could leak in the case of a data breach.
I was thinking about the following protocol (for the encryption):
- the server generates a one-time key (OTK) and a transaction id (TID)
- the server sends a push notification to the device containing the TID
- the device sends the TID to the server via HTTPS, receives the plain-text OTK in response
- the device encrypts the plain-text OTK with a password known only to the device and "forgets" the plain-text OTK
- the device sends the encrypted OTK and the TID via HTTPS to the server
- the server uses some symmetric encryption algorithm to encrypt the data with the plain-text OTK, and then "forgets" the plain-text OTK
- the server stores the encrypted data together with the encrypted OTK
For the decryption, the protocol is similar.
So my questions are:
- Is this approach reasonably secure (by "reasonably" I mean at least as secure as other involved protocols, like OTK generation, HTTPS and some chosen symmetric encryption protocol used on the server)?
- Are there any other patterns to do something like this?
- Are there any known implementations of these patterns (for any kind of backend, any kind of a mobile device)?