Devices: In this system, users have one or more wearable devices (a smart watch), one of which they will most likely have on their person all the time. The devices are linked to their account by their serial number.
Users must have a mobile device linked to their account too. In fact, the watch can only accesses the network through the mobile device.
Access: Users must be able to access their personal data on their watches and their linked mobile device. They should also be able to access their personal data on devices that are not linked to their account, such as a PC or another mobile device, via a Web app.
The server storing their data should not be able to read it, but must be able to store new data for the user. You see where I'm going. But wait…
Customer service agents should, with the user's permission, be able to (temporarily) access their data. It can be assumed that the user, when they wish to grant that permission, has a channel open with customer service (phone call or physical conversation) other than the Internet.
So how do I make that work?
And since I am not a cryptography expert, I'm sure I've left gaping holes in my scheme, so please tell me.
My current plan is to generate a private key on each device at the time the user links it to their account. The public key is sent to the server and associated with the user account and hashed device ID.
All the user's data (it won't be large) on the server is encrypted with all their public keys (so any linked device can decrypt it), PGP-style.
When the user links a new device to an existing account, or wants to access their data on an unliked device (that has no associated key pair) or share it with customer service,
- user is prompted to turn on any of their linked devices
- the linked device generates a short random code (would 6-digit work?)
- user (or customer service agent) enters the number into the unlinked device or Web app
- both ends perform key derivation on the code with some server-generated salt
- the linked device decrypts the user's data, encrypts it with the shared symmetric key and sends it back to the server
- the other device (or customer service agent) can use the newly-encrypted data for an hour or two, then the server deletes it
Obviously, the weak code used for key derivation could be easily brute-forced if the attacker has some encrypted data to try derived keys against. That data won't be stored by us forever, but I suppose it could be stolen and stored by an attacker. How can I make that part stronger? is there some secure way to do time-sensitive key derivation so that the derivation cannot be reproduced an few minutes later (or however long it might take to brute-force a 6-digit code with a decent key derivation scheme)?