0

I am new to PHP and so far created a login, register and a forgot password where currently the user is sent their password from the MySQL table. I have now encrypted the password using sha1 . I am currently writing code so:

When the user clicks on forget password link they enter username and email address (validated).

I am currently finding it difficult to then send them a url link in the sent email to direct them to a page to reset.

Any help would be much appreciated (code snippets, tutorials, links to methods ect.)

Ta

Shimsham84
  • 227
  • 2
  • 12
  • 29
  • Can you post the code you use for this? Kind of hard to help with such an open ended question. – sean Jul 31 '12 at 15:57
  • Where you say you have 'encrypted the password using sha1' I believe you actually mean you have hashed the password. In order to help effectively, it would be good if you could post the code you currently have which isn't working correctly. – infojolt Jul 31 '12 at 15:58
  • As stated in [the introduction](http://www.php.net/manual/en/intro.mysql.php) to the PHP manual chapter on the `mysql_*` functions: *This extension is not recommended for writing new code. Instead, either the [mysqli](http://www.php.net/manual/en/book.mysqli.php) or [PDO_MySQL](http://www.php.net/manual/en/ref.pdo-mysql.php) extension should be used. See also the [MySQL API Overview](http://www.php.net/manual/en/mysqlinfo.api.choosing.php) for further help while choosing a MySQL API.* – eggyal Jul 31 '12 at 16:12

1 Answers1

5
  1. You shouldn't even store (unsalted) hashes of your user's passwords: you should first generate a random string (the "salt"), concatenate it with their password, hash the result (using SHA1, or whichever algorithm you prefer) and store both the hash and the salt in your database. This defeats precomputed dictionary ("rainbow table") attacks should an attacker ever gain access to the hashes in your database.

  2. Having done that, you shouldn't store the temporary token for password resets in your database either: should an attacker gain access to your users table, they merely need complete your "I've forgotten my password" form and read the token from the database in order to then reset that user's password without ever seeing the generated email. As such, the token is known as a "password equivalent" and should be protected in exactly the same way as a password itself: salted and hashed.

  3. Having stored the salted hash of the reset token, you can now send a link to your user with the user's ID and reset token in the querystring of the URL e.g. http://www.example.com/resetpassword.php?user=235747&token=347659864124567532256.

  4. Upon following that link, the provided user and token will be available to your PHP script as $_GET['user'] and $_GET['token']; you can then retrieve the salt from the database, concatenate with the provided token, compute the expected hash and compare with that in the database record. If they match, you have confidence that the user received the email that you sent and you can then prompt them for their desired new password.

eggyal
  • 122,705
  • 18
  • 212
  • 237
  • Thanks for this information, i am assuming this could be done by defining the variable for eg $salt = sha1(md5($password));. When researching i heard of the rainbow table but not methods of "salt" so thanks. – Shimsham84 Jul 31 '12 at 16:18
  • @Bailey1990: No, the salt should be *random*: see http://stackoverflow.com/a/1551064/623041 – eggyal Jul 31 '12 at 16:25
  • +1 for the thorough lesson on making your passwords secure. Though I need to ask...assuming that an attacker obtained access to the user table...wouldn't he also gain access to the salt that way? And, just assuming here of course, that he 'knows', what algorithm the page uses, wouldn't he be able to get access that way too? – ATaylor Aug 01 '12 at 08:27
  • 1
    @ATaylor: With read access to the user table, an attacker would indeed discover the salt - but this only enables her to perform an offline brute-force attack on each password (in the presence of a sufficiently secure hashing algorithm one would expect this to take substantial time, even if the attacker has significant computing resources: knowing the algorithm does not help as, by definition, hash functions are irreversible). Without salt, most of this work can be done beforehand (and shared across multiple attacks), significantly reducing the time to crack each password. – eggyal Aug 01 '12 at 08:40
  • Ah, I see. Yes, I believe to remember, that a 'perfectly safe password' is not possible, just like a lock, that's impossible to crack cannot exist...one can only make it so damn hard, that the attacker has to give up. Thank you for the explanation. – ATaylor Aug 01 '12 at 08:43
  • Thanks for the post, I've read over quite a few of these and this seems to cover it pretty well. Would be nice if you showed what method to use to get a truly unique string though since this is discussed in lots of places but nothing definitive I've found, for now I'm using this uniqid(md5(mt_rand()), true) and will use pHPass to generate a hash to store in the DB and will use pHPass with the token to verify. – shaunhusain Oct 20 '13 at 04:49