3

For user's password entered in a form before post, I simply just do

<?php
   $pass=crypt($_POST['memberpwd']);   
?>

But how can I later get the plaintext of that password in case the user may request ? Thank you.

EDIT: I found How can I encrypt password data in a database using PHP? and http://www.securityfocus.com/blogs/262, but I would just want to learn about this at a more basic level to understand the ways as to how it actually works.

Community
  • 1
  • 1
Mackintoast
  • 1,397
  • 5
  • 17
  • 25

5 Answers5

9

Always store a password in a database using only a hash of (the pasword and a randomly generated salt) (googling for these terms combined with PHP should yield some useful results).

You never restore a plaintext version of the password, you provide means for the user to choose a new password after the user clicks on a unique referral url you only send out by email automatically on request.

(Very basic security).

EDIT:

I'll explain why you need the salt. Suppose someone compromised your database and has the user table with simple (e.g. MD5) password hashes. He (or she) can now simply launch a dictionary attack against the whole table with simple password combinations (e.g. select * from users where pw_hash = ...). If you use a randomly generated (but stored) salt to be used in the hashing of the password, this brute forcing attack gets exponentially harder to exploit.

ChristopheD
  • 112,638
  • 29
  • 165
  • 179
3

The first thing to understand is exactly what crypt() does. Start off by reading this: http://php.net/manual/en/function.crypt.php

Essentially, crypt() is a hashing function. To be more exact, it is a one-way hashing function. As such you aren't going to be able to recover the password from it.

In today's world when a user has "forgotten" their password the best way of handling it is to create a new password, store that and email it to them.

By doing this you are ensuring that if they used the same password for multiple services you aren't inadvertently exposing those other services to nefarious people. Second, if it isn't the original user requesting the password, the next time they try to log in they'll notice their password doesn't work anymore.

NotMe
  • 87,343
  • 27
  • 171
  • 245
2

Look at my answer to a related question.


Basically, you never ever ever store plaintext passwords. Databases can be compromised and most users use a universal password, which will allow the attacked to have access to tons of data. And it will be your fault (to some extent).

Hashing (in your case) works on this principle:

if hash(session.password) == database.hashed_password:
   # You can safely assume session.password == database.password.
   # Notice that I don't store database.password, but instead store:
   #
   #    database.hashed_password = hash(register.password)
   #
   # when the user registers. That way nobody will ever know the password.

You can also use salts to make your hashes more secure. The same principle holds:

if hash(session.password + 'imasalt') == database.hashed_password_with_salt:
   # Same as above.
Community
  • 1
  • 1
Blender
  • 289,723
  • 53
  • 439
  • 496
  • Correct answer, but in real life (for the reason stated in my answer) you'll want to add a salt next to the hash. – ChristopheD Jan 25 '12 at 22:50
  • Yes, +1 for your reply too. I chose his answer because that was what I would like to know, esp within #'s. – Mackintoast Jan 25 '12 at 22:58
  • @ChristopheD: In my database, I salt with the user's registration date converted into a UNIX timestamp. I'll include that as well. – Blender Jan 26 '12 at 03:08
  • 1
    @Blender: that's not random! The salt should be completely random. – Borealid Jan 26 '12 at 03:34
  • Random enough for me. Is `sha512(sha512(user) + sha512(email) + sha512(password) + sha512(timestamp))` not good enough? – Blender Jan 26 '12 at 04:01
  • Also, the salt doesn't have to be random. You have to get it from somewhere. If an attacker got into your database, they'd know your salt as well. – Blender Jan 26 '12 at 04:06
1

Common practice is to use a one-way hash algorithm like SHA (and MD5 in the past). These cannot be reversed. If your user need to recover a password, the system usually resets it and tell the user the new password.

If you want two-way encryption (highly discouraged to store passwords) then your application will need to keep a secret (or have the user provide it).

Take a look at mcrypt http://php.net/manual/en/book.mcrypt.php

Martin Samson
  • 3,970
  • 21
  • 25
1

You don't. If they've forgotten their password, you should reset it and send them an email to create a new one, or something along those lines. Storing passwords in a way that means they can be decrypted and retrieved is very insecure and could, possibly, be illegal in some countries (I'm not a lawyer).

Bojangles
  • 99,427
  • 50
  • 170
  • 208