I'm working on a proof-of-concept program to encrypt email with less difficulty for end-users with a process like:
To create an account:
- Generate a random salt and IV, and get a password from the user.
- Generate a 384-bit key with PBDKF2-HMAC-SHA512 (or maybe scrypt?).
- Split that into three 128-bit keys (k1, k2, k3).
- Generate an RSA key pair (for GPG).
- Encrypt the private key with k3.
- Generate an HMAC of the encrypted private key, using k2.
- Send the salt, IV, k1, number of iterations, public key, HMAC and encrypted private key to the server.
To log in:
- Request our salt and number of iterations from the server (maybe do something here to prevent leaking of email addresses).
- Regenerate k1, k2, k3 with PBKDF2.
- Send k1 to the server, which checks it against its stored version. This is used to prevent making the encrypted key public. Theoretically, this shouldn't matter, but it seems better to protect the encrypted data just in case.
- If k1 matches, the server sends back an AES-128 encrypted private key and IV, with an HMAC-SHA-1 MAC.
- Use k2 to verify the HMAC.
- Use k3 to decrypt the private key.
For future logins, we can simplify things since the server has the public key and we have the private key.
The idea is that even if the server is compromised, the only information it has is k1, the salt, the IV, and the encrypted private key, but to mess with the key, it needs k2, and to decrypt the key it needs k3.
Since the client only needs to decrypt the key once (and can then store it in their operating system's keyring), the number of iterations could be really high.
Am I correct in assuming that this would protect clients against a compromised server? I think the only attack vectors left would be hacking the client, brute forcing the password (which should be incredibly difficult, since we can use a lot of iterations of PBKDF2), and rubber-hose cryptanalysis.
EDIT: More specifically, this is meant to protect a user's password, private key and encrypted emails from an attacker, even if that attacker is working with the owner of the server. Unencrypted emails are basically impossible to protect, since an attacker in control of the server could just save them all off as they come in. Social engineering and rubber hose cryptanalysis are relevant, but my goal was mainly to reduce the possible attacks to ones that can't be kept secret.