views:

26

answers:

2

I'm building a web service which takes credentials for other services and polls these on the users behalf. Ie - consider an email aggregation service - polls your accounts at various different email providers, and collates them in a single list.

In this scenario, passwords provided by the user must be able to be decrypted by the webapp, so they can be passed to various services' for authentication.

How should I store these passwords?

I've read various posts on SO about storing passwords in db's (the answer is always 'don't'.), but in this instance I can't see an alternative. (suggestions welcomed though)

A: 

You could store the hash of the passwords using a secure cryptographic hash such as the SHA series (SHA-1, SHA-512, etc.). Then, to authenticate, hash the inputted password and compare it with the stored hash. That way, you never store the actual password there - only a (generally) non-reversible hash.

Delan Azabani
-1 missing the point. I'd subtract another 1 if I could, since you forgot about salting.
tc.
If I'm missing the point, then what is the point exactly?
Delan Azabani
The point is that Gmail can check your other mail accounts for you. It does this by knowing your plaintext password.
tc.
A: 

Let's clarify something here: The server must be able to recover the plaintext password.

Consider some things you might do:

  • Encrypt the passwords with a key. Store the key in a config file.
  • Encrypt the passwords with a smart card/black box.
  • Encrypt/decrypt the passwords with the aid of another server by sending HTTPS requests.
  • Encrypt the key with a key in RAM. Use mlock() to stop it from being swapped to disk. Hope that you don't have to restart.

None of them help you if the attacker has root (but nothing does). Most of them don't help you if the attacker cuts the power and steals the boxes (RAM is not as non-volatile as you'd like for the purpose).

What attacks are you trying to defend against? What attacks are you ignoring?

One possibility is to encrypt passwords with a key derived from the user's password (like OSX's Keychain, and Windows's equivalent password-storage which nobody uses). When the user is logged on to your web service, you can keep the key in the session (or XOR it with a one-time pad and store the pad in a cookie, and only recover the key when the user sends a request). This makes stealing external passwords from a database backup at least as difficult as cracking the user's password. It doesn't help much against the others, though.

tc.