How to design a cryptographically secure file hosting service How would one go about designing something like Google Drive/Dropbox providing the following features:


files are encrypted and decrypted on the client
files can be synced between devices
the service provider shouldn't be store private keys/passwords on servers
if the user can have only one password to remember that'd be great (we want to design something user friendly)
ideally one could share files with other users


So I thought about a couple of things which don't quite solve the problems.

Using AES to encrypt files

So the first idea is that each user has one password. Now to encrypt a file we derive a long enough AES key from this password (by hashing it and taking the first N bits of the hash) and we encrypt the file. Decryption can only be done if we have the original password.

This fulfills requirements #1, #2, #3, #4.

But I see several potential drawbacks: first files cannot be shared (unless we decrypt them...). Also how bad would that be to derive the AES key from a hashed password? And how bad would that be to reuse the same AES key again and again?

Using a public/private key encryption scheme

To encrypt a file: generate a key pair, encrypt with the public key, save this to the servers. To decrypt use the private key.

This fulfills requirements #1, #2*, #3.

[*] while files can be synced between devices we don't have a user friendly way to pass private keys around (because the user would have to store them 'offline' and carry them with him 24/7)

Sharing is also an issue. Let's consider that Alice stores a file foo.bar and wants to share it with Bob. The only way to do that would be for Alice to decrypt the file locally and reencrypt it with Bob's public key and then send this to Bob. This is cumbersome because it means that sharing takes time and needs Alice to be 'online' to be able to send the new encrypted file.

tl;dr

Is there a way to design such a system without any of the aforementioned drawbacks/flaws?
Generate key-pair
Generate random salt, hash password with proper password hash (scrypt or PBKDF2) to derive a master key.
Use HKDF to derive one login key and one encryption key from master key
Encrypt private key with encryption key from previous step
Upload it to server, download only possible by proving possession of login key (either send over SSL, or use SRP)
Encrypt files with random AES key, encrypt AES key to public key of a user