PHP Security: Password hashing

Sdílet
Vložit
  • čas přidán 21. 07. 2024
  • Want more? Explore the library at www.codecourse.com/lessons
    Official site
    www.codecourse.com
    Twitter
    / teamcodecourse

Komentáře • 52

  • @samsek123
    @samsek123 Před 8 lety +14

    I love this series! Make more security related video!

  • @YPOC
    @YPOC Před 8 lety +1

    Hey Alex, thanks for finally making a series on php security. Love it so far!

  • @B20C0
    @B20C0 Před 7 lety +11

    First of all, thanks for spreading the new easier security mechanisms of PHP and showing how it works. I just have some things to add here because you don't really explain why people should use the php default (currently bcrypt) instead of md5. Given the "cost"-argument in your video you could also just salt a password and still use md5 with a number of iterations, that would eliminate the chances of breaking your password with the help of rainbow tables (this is what is used in your example, not a dictionary, a dictionary is just a list of common clear text passwords, not md5 hashes).
    The real reason why you shouldn't use md5 anymore is because it is computed WAY too fast, not because the algorithm itself is weak. The real danger today lies in brute force attacks, basically checking a hash against any given number of passwords until it matches. Also md5 is GPU friendly, and GPUs are currently being used a lot to crack passwords. If you spend around 20,000$ you can build a machine that computes 100 BILLION hashes per second (not exaggerating here and yes, this has been done already, trading user accounts with passwords is a pretty profitable business these days). That is because GPUs are pretty great at parallel computing.
    So basically even if you add iterations to md5 that are typical for bcrypt (eg. 2^12), you still can check against ~ 24 million passwords per second with such a machine.
    Bcrypt prevents this because it uses data-dependent lookups in a 4 kB table which can't be accessed by all threads at once, therefore effectively taking parallel computing out of the equation and increasing the computing time for each hash dramatically. With md5, you can compute as many hashes per second as you want as long as you add more GPUs or CPUs, aka more parallel computing but with bcrypt the computing is limited to the actual processing power of a single thread.
    That is also the reason why articles claiming that bcrypt is "100-times"/"10 million times" slower than md5 are bullshit, bcrypt is just a little bit slower than md5 if compared thread by thread but it only has one thread per instance and that is why bcrypt becomes indefinitely slower than md5 the more parallel computing comes into play.
    And finally one thing about the cost: The cost is the EXPONENT of the number of iterations, not the actual number of iterations itself. This means basically that the password is hashed, then the hash is hashed again etc., 2^COST times.
    This means that an increase of 1 at the cost DOUBLES the number iterations therefore doubling the computing time.
    E.g.: computing the hash for one password with a cost of 12 (which is considered enough as of 2016) on an i3 with 3.3 GHz is around 0.25 seconds. Checking against 24 million passwords (which can be done within 1 second on md5 with a proper built and configurated machine) would then take ~ 69 days with bcrypt. You can only speed things up by having a faster single thread, and lets say you use a 10GHz machine, it would still take ~22 days.
    However, this does not mean that your 3.3 GHz machine takes 1 second to authenticate 4 users given my example above (4x 0.25 seconds) as every instance of bcrypt can use its own thread, you just cant parallel compute a single instance.
    That's why it's no problem for services like Twitter to use bcrypt with millions of users, thousands logging in at the same time.
    But even with all of this in mind, NOTHING protects you against the idiocy of people so you should also force them to pick passwords at least 8 characters in length of at least 3 different types (lowercase, uppercase, numbers, special characters). Not because special characters and numbers are more safe against brute force but because they are safer against dictionary attacks and it's easier to check against that when the user choses his password. However I once wrote a script that used a point system to determine password strength and at a specific length the password was considered safe no matter the types of input as long as it wasn't only numbers.
    In reality, a password like "MeAndMyFriendWentToMyAuntsHorseAndAteApplePie" is MUCH safer than "jdia$%&ajdADK" because simply put, it is longer and while a dictionary contains every single word of that password it doesn't contain THIS combination of words. Explanation: xkcd.com/936/
    TLDR:
    - BCRYPT is better than md5 because it is SLOWER and can't be computed parallel
    - an increase of 1 in cost DOUBLES the computing time
    - make sure your users choose safe passwords
    And one final tip for users:
    Try to use different passwords for every service you use. I know it sucks but if one service screws up (as seen countless times in the past, just saying Sony, Adobe, Microsoft) you have to change ALL your passwords.
    A thing that helps: use a password manager like KeyPassX. Basically you store all your passwords in one encrypted container, you just need one password to unlock it. You don't even have to know your passwords anymore, you can just copy and paste them without them even turning up on your screen (another security feature).

    • @IgorAherne
      @IgorAherne Před 7 lety

      wow, cheers for this great information!

    • @B20C0
      @B20C0 Před 7 lety

      You're welcome, being a nerd with too much spare time must be good for something :D

    • @informatiqueconstantine8851
      @informatiqueconstantine8851 Před 7 lety

      Thank you

    • @fuseteam
      @fuseteam Před 5 lety

      thanks for this post, this makes some things clearer
      but one thing i can't wrap my head around is how hiding all you passwords behind one password makes it more secure tbh

  • @HasanAlmancie
    @HasanAlmancie Před 8 lety +6

    This library is actually available on github for older versions of PHP.

  • @phillipscards
    @phillipscards Před 8 lety

    Thanks for this tutorial, Alex!

  • @AasimSajjad
    @AasimSajjad Před 8 lety

    Thanx Alex .... love the series

  • @designanddevelop585
    @designanddevelop585 Před 8 lety

    video I've been looking for

  • @101BVE
    @101BVE Před 8 lety

    Thank you, so much for this.

  • @jasworld9672
    @jasworld9672 Před 5 lety

    What will be the default value of cost , since I have used this algorithm but not passed such variable inside it

  • @khalidmohd882
    @khalidmohd882 Před 7 lety +2

    First of all I would like to thank you for these precious information. As you told that Websites like Crackstation do not de-crypt that. They just have a dictionary for some well frequently used passwords. They just match that and return. But if you enter some random and usually difficult passwords, they dont find any match for that. My question is why wouldn't someone again make another dictionary for password_hash() like md5 ? If so happens, then what is the difference of using it instead of md5 ?

    • @fuseteam
      @fuseteam Před 5 lety

      one difference is random salts, even if they do make one changes are the salts won't matck....... at least that's what i can gleem

  • @markshall94
    @markshall94 Před 8 lety +2

    May sound daft, but would it also make sense to hash the returned value from password_hash() in md5(), that way, a hacker would pretty much never be able to tell that we've used password_hash(), it just looks like a normal md5() hash?

    • @B20C0
      @B20C0 Před 7 lety

      From a programming standpoint I like the fact that password_hash() was introduced because I don't have to write my own hashing function anymore and can rely on the fact that password_hash() uses best practice methods. It also makes your code much more easy to understand (which is good if you work in a team).
      On the other hand it's a good idea to obscure the password even more but I don't really think it adds a big layer of security since md5 is easily computed.
      Though it might be funny to see a hackers face lighten up because he smells an easy prey when he sees md5 hashes in a database, then starts his brute force machine just to find out that after 2 days of computing he's been left with a bcrypt hash.

  • @alfarica9059
    @alfarica9059 Před 7 lety +1

    thank for your explaination. but can you explain to implement this encryption in the mysql query in order to encrypt current data I have already collected? thanks

    • @fuseteam
      @fuseteam Před 5 lety

      this would be usefull yeah

  • @aleksajoksimovic8898
    @aleksajoksimovic8898 Před 8 lety

    Great video!

  • @rw7799
    @rw7799 Před 6 lety

    awesome explain, was hoping you would put the new hash into the hack app to see what it said . could do with real world script......find it difficult to transfer your cold code into real world .

  • @CJBurkey
    @CJBurkey Před 8 lety

    My host is for some reason still using 5.4. On their website they even say that that version is deprecated and insecure lol.

  • @THEunderscoreJOKE
    @THEunderscoreJOKE Před 8 lety

    What is the salt generated from?

  • @jipirfandy668
    @jipirfandy668 Před 5 lety

    Do I have to encrypt it again in database, so DBA can't access it?

  • @kanu6532
    @kanu6532 Před 8 lety

    Thank you Alex for this video. I would like to ask you how to store the password in phpmyadmin. Do I need to copy and paste into phpmyadmin?

    • @Dexter101x
      @Dexter101x Před 7 lety

      I'm not alex, but yeah you can copy and paste it, but you can also make a script to insert it into database. A lot better to make script

  • @sagarplayer2008sh
    @sagarplayer2008sh Před 7 lety

    please provide php code for create an encrypted PDF in PHP that can be decrypted after download within PDF Reader?

  • @sirajS
    @sirajS Před 7 lety

    thanks a ton... :)

  • @DavidAshby1
    @DavidAshby1 Před 8 lety

    Prior to watching this my version of Xampp was running version 5.4.7 php, I have upgraded to version 5.6.2 which appears to be the latest version.
    I tried to follow this tutorial by entering
    echo password_hash('ilovecats33', PASSWORD_DEFAULT, ['cost' => 12]);
    I got an error so I took the code back to
    echo password_hash('ilovecats33', PASSWORD_DEFAULT);
    This worked, it generated an hashed password
    Can someone tell me why the ['cost' => 20] is causing an issue?
    In addition Xampp is saying that php is running on port 80 but the button on the console is still saying start.
    Thanks for any help.

    • @DavidAshby1
      @DavidAshby1 Před 8 lety

      +David Ashby After reading www.sitepoint.com/hashing-passwords-php-5-5-password-hashing-api/ and seeing that you do not need to use the cost and as Alex said you shouldn't use the salt as is deprecated the following code generates a password long enough $2y$10$fWrKTDiKPm8kVIN5qNh0UeybEV68sycsEAGKJQXRnXqyvvXTYyuV6
      echo password_hash('ilovecats33', PASSWORD_DEFAULT);

    • @DavidAshby1
      @DavidAshby1 Před 8 lety

      +David Ashby var_dump ( password_get_info ($hash) );

  • @7T0m
    @7T0m Před 6 lety

    Any tip to turn it into classic if statement ? if password_verify == true {***}

    • @ashkanahmadi
      @ashkanahmadi Před 3 lety

      password_verify returns true or false. then you can use
      if (password_verify($submitted, $hashed) === true) { .... }

  • @raylee141414
    @raylee141414 Před 4 lety

    i love you Alex (not gay)
    btw, you teach us in your oop login/ register system tutorial to use salt and hash to save passwords.
    do password_hash and password_verify replace the old method?

  • @Actarsatan
    @Actarsatan Před 8 lety

    But what about we use password_needs_rehash after each login,that would be usefull, right?

    • @ArtstersRecords
      @ArtstersRecords Před 8 lety

      +Enrico Signori you are thinking about that great way, but the problem is, you can get the value from the old hash, too, it's just encrypted password. The only way is to generate such a big passwords.

    • @jarmo_kiiski
      @jarmo_kiiski Před 8 lety

      A better way would be to make your own hashing function.

    • @B20C0
      @B20C0 Před 7 lety

      That is complete and utter bullshit. What would you write then? Because all the custom hashing functions I saw so far were absolute garbage. Unless you are a math genius who knows how to write a safe one way algorithm (that is what hashes are) you will make your application insecure.

    • @jarmo_kiiski
      @jarmo_kiiski Před 7 lety

      B20C0 Let me show you a sample from my hashing function : "This is a test!" = 2$325$4f3a7e01c09ae74e8933/.0*1.1*1.2*0.2*2.4*2.6*0.6*1.7*3.10*5.15*0/0f57e3f3f8f45da5d490331cd629195c03d8c8388c840524abacc8ede7a70c6f43c05e0fbcc7feb31ce5c8cb7e3b3cb0984d3ce95ea89044216fbba1022916c6c26655bc0ff131209b0c5a9a0b40faa5fc4dcfbfaa8c65d658399a40e3f0e3ff5b0f465d31b865815c500d9219817b844f35ebcaddbbd4b41e77b517779220204674c5ee1f3e96e77862cacd5673d34ab6a4e9474ab5c1f2365802f349fe1c11990d8e9afb5c00cecc450239be05293a4bdb93ad4c60d8504c0cabe30c8cd1f20d00a8dab2c0936d5d0515b4d5dafd30e54ef2a309a14e6d8182412c28531470323f3c19aaa3c44a20daf70e126cceaec48a0c74c8/.0*5*59.5*0*49.5*10*57.15*2*52.17*12*52.29*3*42.32*3*44.35*0*46.35*3*49.38*2*/d9e5f1728b04b9dafbd11f633cd

    • @B20C0
      @B20C0 Před 7 lety

      shlev
      That is not a hash function that's a bunch of bullshit.

  • @theevildice83
    @theevildice83 Před 6 lety

    Call me paranoid, but I generate a salt based on the username, hash the input with sha256, then split the salt and append it to each end of the hash, then hash it again with sha256 again, split the it in two and put the second half at the front, then reverse the whole thing and store it. May be a little overboard but... Meh.

    • @michaelwilson6861
      @michaelwilson6861 Před 6 lety +1

      Who's a good human, who's a good human! You are, you are!!!!!!!!