views:

1242

answers:

4

I would like to encrypt the passwords on my site using a 2-way encryption within PHP. I have come across the mcrypt library, but it seems so cumbersome. Anyone know of any other methods that are easier, but yet secure? I do have access to the Zend Framework, so a solution using it would do as well.

I actually need the 2-way encryption because my client wants to go into the db and change the password or retrieve it.

+4  A: 

Don't encrypt passwords. You never really need to decrypt them, you only need to verify them. Using mcrypt is not much better than doing nothing at all, since if a hacker broke into your site and stole the encrypted passwords, they would probably also be able to steal the key used to encrypt them.

Create a single "password" function for your php application where you take the user's password, concatenate it with a salt and run the resulting string through the sha-256 hashing function and return the result. Whenever you need to verify a password, you only need to verify that the hash of the password matches the hash in the database.

http://phpsec.org/articles/2005/password-hashing.html

Jesse Weigert
Thx. I just added this line to my question - I actually need the 2-way encryption because my client wants to go into the db and change the password or retrieve it.
Bamerza
Well, you might as well just XOR the password with the key "PleaseHackMe". Seriously though, convince your client that they only need to reset the password -- not retrieve it.
Jesse Weigert
This is a good answer, except that I would not recommend the SHA-1 algorithm, which has been shown to be more easily breakable than it should be. I'd recommend SHA-256, or one of that family (SHA-384, SHA-512, etc).
thomasrutter
+2  A: 

When you really need to retrieve the passwords later on, you should at least use private and public keys so an attacker would need the private key (which shouldn't be stored on the same machine) to decrypt the passwords.

The 2 functions to accomplish this goal are openssl_public_encrypt() and openssl_private_decrypt()

tstenner
This sounds like the only method to accomplish this goal and having some security at least.
Georg
M_CRYPT is the library that was designed for data encryption and decryption stuff, the OpenSSL library is used for secret/secured communications.
Jacco
This is a fair enough answer. I would also add to that that you should not ever store the private key anywhere on the same server or any related server. It is relatively easy to search an entire hard disk for a key.
thomasrutter
+9  A: 

You should store passwords hashed (and properly salted).

There is no excuse in the world that is good enough to break this rule.

Currently, using crypt, with CRYPT_BLOWFISH is the best practice.
CRYPT_BLOWFISH in PHP is an implementation of the Bcrypt hash. Bcrypt is based on the Blowfish block cipher.

  • If your client tries to login, you hash the entered password and compare it to the hash stored in the DB. if they match, access is granted.

  • If your client wants to change the password, they will need to do it trough some little script, that properly hashes the new password and stores it into the DB.

  • If your client wants to recover a password, a new random password should be generated and send to your client. The hash of the new password is stored in the DB

  • If your clients want to look up the current password, they are out of luck. And that is exactly the point of hashing password: the system does not know the password, so it can never be 'looked up'/stolen.

Jeff blogged about it: You're Probably Storing Passwords Incorrectly

If you want to use a standard library, you could take a look at: Portable PHP password hashing framework and make sure you use the CRYPT_BLOWFISH algorithm.

(Generally speaking, messing around with the records in your database directly is asking for trouble.
Many people -including very experienced DB administrators- have found that out the hard way.)

Jacco
I think you want to edit your first statement to read: "You should store passwords hashed"
Jesse Weigert
Eeeeh, yes, thanks :)
Jacco
Did you mean to write Blowfish here? Blowfish == symmetric key encryption, not hashing. I would strongly recommend hashing over encryption.
thomasrutter
Blowfish with PHP's crypt (CRYPT_BLOWFISH flag) is a Bcrypt implementation; designed to be a strong hashing algorithm, based on Blowfish.
Jacco
+1  A: 

Either store it in the clear, or store a hash (i.e. NOT reversible) of the password.

Doing anything else - particularly using symmetric encryption with a hard-coded key - is basically pointless.

If you do as you suggest and your machine were compromised, the attacker gains access to not only the encrypted passwords, but also the code and the key to decrypt them, so they may as well have been stored in the clear.

If you want to protect your data against someone obtaining physical access to the machine, use an encrypted filesystem (but still store the password in the clear in the database in it). Of course each reboot, you'll need to manually enter the key before the system is usable.

MarkR