For learning purposes I am trying to build a web application (Symfony2, PHP) that allows users to post content and have their own password vault, everything encrypted. Since I want to users to be able to share passwords and encrypted content I chose asymmetric encryption for generating a key pair for each user.
I will store users key pairs in the database but I will encrypt each user private key with AES-256. When the user signs in, he should be able to view his passwords and content he has access to without any user extra input.
That's the general idea.
Now to the practical solution.
- Generate 4096-bit keys
- Generate session key, PBKDF2(user password)
- Encrypt private key with session key
- Store key in database
- Generate a random storage key
- Encrypt password with storage key using AES-256
- Encrypt storage key with user public key
- Store encrypted storage key
- User enters password
- Compute session key from password, PBKDF2(user password)
- Store session key in session
- User requests encrypted content - decrypt storage key with user private key
- Decrypt content/password(AES-256) with storage key
As I see it, there are two main disadvantages with this scheme.
I store the decryption key (seesion key) in the users session, which I'm not certain if it is written to /tmp folder. An attacker could perhaps use some form of session hijacking or if he had access to server read the /tmp folder.
The users private key is not passphrase protected!
Session encryption? Or maybe that's not needed since symfony2 handles session data sufficiently?
Generate random string to be used as passphrase, encrypt this passphrase and store in the database. Or use PBKDF2(session key) as passphrase ?
The goal is to be able to protect the users passwords & content as much as possible even though the attacker has access to the database or server.
Does my plan sound "good", or should I just scrap it? Any feedback?