Advanced Search

Page 1 of 5 123 ... LastLast
Results 1 to 10 of 48

Thread: How do you retrieve a hashed password?

  1. #1
    Join Date
    Jan 2007
    Location
    Davenport, Iowa
    Posts
    1,681
    Thanks
    78
    Thanked 89 Times in 87 Posts

    Default How do you retrieve a hashed password?

    A while back I heard that a web designer should never store a plain text password anywhere. I can see how that can be done, but let's say the visitor to your site has forgotten his password. I would imagine that his password is stored in the database in md5 format. How do you retrieve that password in plain text format so that it can be emailed to the person requesting it?

    On another note I just noticed that you can now rate up or down comments on php.net!

    I get a kick out of little things like that.

    EDIT: On a related note there are md5 decryption programs out there. Would double or triple md5 encryption be a good enough deterrent for the average hacker? Either way I imagine just getting the hashed password of any ol' user is difficult enough to get.
    Last edited by james438; 02-03-2013 at 06:21 AM. Reason: wording error
    To choose the lesser of two evils is still to choose evil. My personal site

  2. #2
    Join Date
    Apr 2008
    Location
    So.Cal
    Posts
    3,624
    Thanks
    63
    Thanked 516 Times in 502 Posts
    Blog Entries
    5

    Default

    Quote Originally Posted by james438
    ...let's say the visitor to your site has forgotten his password. I would imagine that his password is stored in the database in md5 format. How do you retrieve that password in plain text format so that it can be emailed to the person requesting it?
    you don't.

    not ever. If it is even possible (for you, as an admin/developer, even with full site/DB access), then your website has a critical security flaw.
    passwords should be reset, not recovered.

    here's a good way to approach it:
    • user clicks your "forgot password" link.
    • website generates a random password hash and stores it in the DB, along with the user account to associate it with and the time it was created.
    • website sends an email with a "password reset" link, which includes the hash (in the URL or query string).
    • user visits the password reset URL.
    • website gets the hash and compares is to the DB records.
    • if there is a match, and it's not too old (they should expire quickly; an hour is more than long enough), the user is allowed to set a new password.
    • DB record is invalidated.
    • user logs in with new password.


    Regarding md5, it's "good enough" for little-to-no security sites, but using other algorithms is preferable. SHA-512 or Whirlpool (using PHP's crypt() function) is best, but you've got the right idea with multiple hashing - even "weak" hashing functions can be made fairly secure this way. It's more like "hundreds," though, not "double" or "triple"; and salting is critical also.

    • receive the password the user choose.
    • generate a salt: an arbitrary string unique to the particular user.
      A salt should be at least as long as the hash generated by the hashing function you're using.
    • combine the password and salt.
      Some implementations break the salt into pieces and intersperse it with the password string.
      You might even introduce more entropy by using different approaches based on the length (or other computed value) of the password.
    • hash the salted password.
      You should do this many times (speed is not an advantage: it should be as slow as practically possible).
      You might re-introduce the salt or vary the total number/sequence of hash iterations based on the password/salt (as above).
      This is called stretching.


    Obviously, you'll have to store the salt in your DB along with the final password hash, so you can recreate this process reliably for each password.
    We Only Torture the Folks We Don't Like (You're Probably Gonna Be Okay)
    It's a Party in the CIA

  3. #3
    Join Date
    Jan 2007
    Location
    Davenport, Iowa
    Posts
    1,681
    Thanks
    78
    Thanked 89 Times in 87 Posts

    Default

    Ah, I was thinking along the wrong lines as far as password retrieval. It took me about 10 seconds to find a website to decrypt md5. I believe I already am salting my passwords. I think you have been to my site before and know that it is just a casual site mostly for my own use, but others can register and post in the forum or write an article if they so choose. In other words a casual site, so the need for high tech security is not critical. I'm curious if it is server heavy to use crypt() in a 100 or 300+ loop to hash a salted password. I'll try to read up more on the link you gave.
    Last edited by james438; 02-06-2013 at 06:15 AM. Reason: grammar
    To choose the lesser of two evils is still to choose evil. My personal site

  4. #4
    Join Date
    Mar 2006
    Location
    Illinois, USA
    Posts
    12,154
    Thanks
    261
    Thanked 690 Times in 678 Posts

    Default

    Traq covered most of it.

    My brief thoughts to add:
    1. Hashing is one way. That's the design. It allows you to know if the two inputs were the same (technically, only with a very very high probability-- there's potential for two inputs to have the same output, but very very rarely, to the point where it's probably irrelevant-- after all, there are only 16^32 possible combinations and the input can be any length.)
    2. There is no "decryption"-- instead, the only way is to compare known pairs-- there are some massive databases out there of MD5 hashes and inputs, so you can do a lookup based just on the database of known pairs (generated by brute force or popularity). So if you have an odd enough input it can't be reversed because they won't have the input.
    3. Salting is a good trick.


    Edit: saw your latest post, james.
    That does sound server intensive to me, and I'm not sure why 100 loops would actually help. There's a point where you're just doing a 32-character string over and over again, so the odds of guessing it won't change at some point, I think. And I don't really see why looping it 2-3 times with salt won't be enough. I'd also suggest adding global salt on your site, just something like your domain name. That way "password" won't have the same hash as it usually would on any other site, regardless of the other aspects of your hash algorithm.

    However, traq probably has a good reason for suggesting doing it so many times, so I'm open to hearing that-- I just personally wouldn't have thought it made sense to do it that much.
    Daniel - Freelance Web Design | <?php?> | <html>| espa˝ol | Deutsch | italiano | portuguŕs | catalÓ | un peu de franšais | some knowledge of several other languages: I can sometimes help translate here on DD | Linguistics Forum

  5. #5
    Join Date
    Apr 2008
    Location
    So.Cal
    Posts
    3,624
    Thanks
    63
    Thanked 516 Times in 502 Posts
    Blog Entries
    5

    Default

    reason being:

    many attacks involve lookup tables: lists of words/phrases and their resultant hashes.
    Moving away from one-time hashing of passwords starts to protect against the risk of finding matching passwords right off the bat.

    When it comes to brute force attacks, the idea is to make the attempt so slow that there's no point in doing it. A hundred iterations seems like a long time to you, but you're only doing it once every time a user logs in. It only takes a fraction of a second. But if you're trying to crack passwords, you have to expect to spend that "fraction of a second" possibly billions of times for each hash.

    this is a good article that explains better than I can.

    Quote Originally Posted by djr33 View Post
    ...I'd also suggest adding global salt on your site, just something like your domain name. That way "password" won't have the same hash as it usually would on any other site, regardless of the other aspects of your hash algorithm.
    it's better to have password-specific salts, for the same reason you cite above: if two users on your site have the same password, they'll still have completely different hashes.

    --------------

    Keep in mind that, once you've moved away from plain text, you've defeated the risk of giving someone's password away (intentionally or not).

    After that, it's all about limiting the damage in case your hashes are leaked/stolen (a very real concern, especially on shared servers). Once they're stolen, the attacker has a lot of time to crack them, and almost certainly will if they're intent enough. You need to slow them down as much as possible to give yourself time to suspend everyone's accounts and direct them to set new passwords.
    We Only Torture the Folks We Don't Like (You're Probably Gonna Be Okay)
    It's a Party in the CIA

  6. #6
    Join Date
    Mar 2006
    Location
    Illinois, USA
    Posts
    12,154
    Thanks
    261
    Thanked 690 Times in 678 Posts

    Default

    Interesting points. Let's see--

    1. I don't see why 100 iterations would be a practical difference. Brute force is very hard to do if you require reasonably long passwords. I can see the argument here, but I don't think it's practical. There are bigger concerns with a site/security, right? But technically, yes, slowing them down would be good.

    2. I don't mean you'd only use site-wide salt. Maybe it's overkill to have both. User-specific salt is useful. But having site-wide salt would accomplish the necessary security of making lookup tables irrelevant. If you append "mysite.com" to each password input, then it just means there's no point in looking anything up in a database because it's very unlikely any passwords ending in "mysite.com" will exist there. User-specific salt should be used too. (And perhaps with user specific salt, there's no point in site-wide salt.)

    Personally, I think something like this is more than sufficient:
    PHP Code:
    $pass md5($pass);
    $pass md5($pass.'mysite.com');
    $pass md5($pass.$username); 
    Note that I added the salt in each time to a hash, rather than directly to the password. I don't know if there's any technical reason that's really more secure, but to me it seems less direct, and it certainly won't hurt.
    (And you could use any hash algorithm you want-- I'm just demonstrating it with md5, which I think is still secure as long as you stay away from anything that might be in a database. I guess at some point there might be an almost complete database of md5 strings out there (at least up to a certain length), but with a few iterations it still seems relatively secure. Do such complete database exist? My impression was that they were only based on limited lists of inputs, not brute force to complete databases.)


    There's also the security of them not knowing your algorithm, assuming your site is secure in the first place. If it's not, then you can be hacked in other ways anyway. The only problem with that logic I can think of would be for software you distribute to others. In that case, it would be vulnerable because the hacker would know what you're working with. (So, it might be a good idea to modify the hashing algorithm in whatever 3rd party software you use, like PHP forums, etc.)
    Daniel - Freelance Web Design | <?php?> | <html>| espa˝ol | Deutsch | italiano | portuguŕs | catalÓ | un peu de franšais | some knowledge of several other languages: I can sometimes help translate here on DD | Linguistics Forum

  7. #7
    Join Date
    Jan 2007
    Location
    Davenport, Iowa
    Posts
    1,681
    Thanks
    78
    Thanked 89 Times in 87 Posts

    Default

    Sorry djr33, but I could crack the code you posted in a few short minutes using a md5 decryption program I just found. crypt() sounds much more secure. Traq, if it is only or mostly about a delay against brute force attacks it sounds like it would be much less processor heavy if I add a wait command. I will and do salt my admin login encryptions though.

    Thank you for the article. There is a fair amount of information to go over there.
    To choose the lesser of two evils is still to choose evil. My personal site

  8. #8
    Join Date
    Mar 2006
    Location
    Illinois, USA
    Posts
    12,154
    Thanks
    261
    Thanked 690 Times in 678 Posts

    Default

    Interesting--
    1. The decryption program you found can do any input? Not just a (potentially long) list of frequent ones? If so, then md5 is effectively dead. That's important to know. I was under the impression that md5('password') was weak (while somethingelse('password') might be relatively strong), while md5('random-new-string-never-used-before') was still (relatively) strong.

    2. There's also the secrecy factor. Assuming no one can see the code you're using, using md5(md5($s)) might be enough. Or, more reasonably, something harder to guess. Maybe md5(sha1(md5($s))), or something else that mixes things up in an unpredictable way.


    There are three pieces to the password puzzle:
    --The hashed string (potentially known)
    --The original password (unknown, except maybe by brute force)
    --The algorithm (best if unknown, only known if they see your code)

    And you need any two of those to figure out the other one, which is technically possible although in some cases very difficult (eg, only via brute force). If the algorithm is compromised (and it is known!), then that's a major security flaw indeed.
    Daniel - Freelance Web Design | <?php?> | <html>| espa˝ol | Deutsch | italiano | portuguŕs | catalÓ | un peu de franšais | some knowledge of several other languages: I can sometimes help translate here on DD | Linguistics Forum

  9. #9
    Join Date
    Jul 2010
    Location
    Minnesota
    Posts
    243
    Thanks
    1
    Thanked 18 Times in 18 Posts

    Default

    Here is a good post to read also from another forum that I am on. There are a few of the guys on there that are very good at security and the understanding of it.
    https://phpacademy.org/forum/topic/p...asswords-15356

  10. #10
    Join Date
    Apr 2008
    Location
    So.Cal
    Posts
    3,624
    Thanks
    63
    Thanked 516 Times in 502 Posts
    Blog Entries
    5

    Default

    Quote Originally Posted by djr33 View Post
    There are bigger concerns with a site/security, right?
    Of course. SSL being the main one; everything you do is useless is it's being sent over HTTP in plain text.

    Also using tokens to identify your forms, and rate-limiting login attempts.

    Quote Originally Posted by djr33 View Post
    2. I don't mean you'd only use site-wide salt. Maybe it's overkill to have both. User-specific salt is useful. But having site-wide salt would accomplish the necessary security of making lookup tables irrelevant.
    Actually, I don't think it's overkill. I'm working on a class right now that will use two salts: one that can be determined client-side (though not the same one for everyone, it will be based on the input), and a stronger one that will be stored in the DB. This way, I'll be able to hash it "halfway," send it to the DB, and have the hash completed there. It saves a round-trip (I don't need to query the DB to get the salt).

    Quote Originally Posted by djr33 View Post
    There's also the security of them not knowing your algorithm, assuming your site is secure in the first place.
    Hashing really accomplishes two different goals:

    1) it should be impossible to produce a plain-text version of the password, either deliberately or by any sort of injection attack/ social hacking/ other trickery. For this purpose, strength is not as critical.

    2) it should be difficult (hopefully "difficult enough" to be considered impractical) to crack the hashes if they are stolen or leaked. That's where a strong algorithm/process is needed.
    ...and don't just figure "you're not a target." james, I'm sure, knows that that's simply not true of anyone. Beyond that, consider the fact that most people use the same password for everything. That's not your fault, of course, and you can't be expected to be responsible for it, but you've probably got someone's bank or email password in there.

    Quote Originally Posted by james438 View Post
    if it is only or mostly about a delay against brute force attacks it sounds like it would be much less processor heavy if I add a wait command.
    no; it's processor-time we're talking about, here. Most brute force password cracking efforts take place on stolen hashes, not on your live site - so it's just a matter of not executing the wait, whereas extra processing can't be skipped.

    Edit: fastol, I'm reading that now.
    Last edited by traq; 12-30-2013 at 02:48 AM.
    We Only Torture the Folks We Don't Like (You're Probably Gonna Be Okay)
    It's a Party in the CIA

Similar Threads

  1. Replies: 4
    Last Post: 01-24-2011, 10:57 AM
  2. Replies: 4
    Last Post: 03-04-2009, 02:36 PM
  3. Replies: 2
    Last Post: 07-01-2008, 11:47 AM
  4. how to retrieve
    By jr_yeo in forum PHP
    Replies: 6
    Last Post: 08-17-2007, 11:18 PM
  5. retrieve files
    By sukanya.paul in forum PHP
    Replies: 2
    Last Post: 04-24-2007, 02:14 PM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •