I'm building a web application that lets user enter their imap-account-information into it, and I need to save it for them for later use.<p>I've been looking at a few ways to encrypt it, but it also has to be easy to decrypt for me when accessing their imap-account. In the same time it should be made reasonably difficult to decrypt them if the database gets stolen for some reason.<p>Is there some best practices here? Any hints would be appreciated. Implementation is in php and mysql currently, but might be python as well(I'm still in the prototype phase).
If your system needs both to encrypt and decrypt some information this to me means that the decryption key has to be stored somewhere and if that somewhere is compromised, so is everything else.<p>I would store the decryption key on the filesystem somewhere obscure, so that if somebody gets into your database, but not the filesystem, the data still remains encrypted.<p>If your filesystem is compromised, all your security measures will quickly become meaningless. You will need to do continuous security monitoring and auditing to make sure that doesn't happen.
Use bcrypt or scrypt to store the passwords. Don't use plain SHA1 or MD5, etc. If you must use SHA1 or MD5 (for whatever reason), iterate and salt them.<p>Edit: Re-reading, I may have mis-understood your question. <i>You</i> want to be able to decrypt and view their plain-text passwords yourself? Is that what you mean when you say "easy for me to decrypt". If that's the case and you need to decrypt it later (on their behalf) disregard my suggestions.
I'm still in the prototype phase of a project with the same problem, and it's the one aspect of it that makes me nervous.<p>Note that you don't always need to store the password - GMail will let you do IMAP using OAuth, and Yahoo has their Mail Applications. My own plan is to launch with support for those and find out a little about demand for the product before we start storing people's passwords.
If the task you're doing with the account-information is asynchronous make it inaccessible from the web frontend (or writeonly, public key encryption) and run your cronjob on a different box with a different database user so that the data is safe if your public facing application gets hacked. Also do not store the passwords in plaintext and store the private key in the safest place possible.