7

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.

Jacco
  • 23,534
  • 17
  • 88
  • 105
Bamerza
  • 1,335
  • 1
  • 18
  • 34
  • 2
    Why does the client want to retrieve the password? This is usually a bad idea. Give the admin facilities to reset the password, and the user the ability to change the password if they know the original. – Roger Lipscombe Mar 15 '09 at 10:06

4 Answers4

27

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.)

Community
  • 1
  • 1
Jacco
  • 23,534
  • 17
  • 88
  • 105
  • I think you want to edit your first statement to read: "You should store passwords hashed" – Jesse Weigert Mar 15 '09 at 11:29
  • 1
    Did you mean to write Blowfish here? Blowfish == symmetric key encryption, not hashing. I would strongly recommend hashing over encryption. – thomasrutter Mar 15 '09 at 12:35
  • Blowfish with PHP's crypt (CRYPT_BLOWFISH flag) is a Bcrypt implementation; designed to be a strong hashing algorithm, based on Blowfish. – Jacco Mar 15 '09 at 14:05
  • This is a nice 'how to encrypt passwords' infomercial - but doesn't actually answer the OP's question. – wbinky Jun 10 '14 at 15:37
  • Why is this the accepted answer? It doesn't provide any information on 2-way encryption at all. – Madbreaks Aug 11 '15 at 19:57
8

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
  • 4,714
  • 5
  • 28
  • 37
  • 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 Mar 15 '09 at 09:21
  • 2
    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 Mar 15 '09 at 11:24
  • 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 Mar 15 '09 at 12:38
4

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
  • 10,080
  • 10
  • 57
  • 92
  • This sounds like the only method to accomplish this goal and having some security at least. – Georg Schölly Mar 15 '09 at 11:38
  • M_CRYPT is the library that was designed for data encryption and decryption stuff, the OpenSSL library is used for secret/secured communications. – Jacco Mar 15 '09 at 11:50
  • 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 Mar 15 '09 at 12:40
1

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
  • 62,604
  • 14
  • 116
  • 151