How to create and store password hashes with Blowfish in PHP

25,838

You should store the entire output of crypt, there's not a lot of point in splitting it up, because you need to generate a new salt for each password you're hashing in any case. Using a fixed hidden salt as mentioned by Matt is wrong - the salt should be different for every hash.

For more information see http://www.openwall.com/articles/PHP-Users-Passwords - I recommend using the phpass library because it handles generating a random salt for you, unlike crypt().

Share:
25,838

Related videos on Youtube

Admin
Author by

Admin

Updated on February 14, 2020

Comments

  • Admin
    Admin about 4 years

    1) How do you create secure Blowfish hashes of passwords with crypt()?

    $hash = crypt('somePassword', '$2a$07$nGYCCmhrzjrgdcxjH$');
    

    1a) What is the significance of "$2a"? Does it just indicate that the Blowfish algorithm should be used?
    1b) What is the significance of "$07"? Does a higher value imply a more secure hash?
    1c) What is the significance of "$nGYCCmhrzjrgdcxjH$"? Is this the salt that will be used? Should this be randomly generated? Hard-coded?

    2) How do you store Blowfish hashes?

    echo $hash;
    //Output: $2a$07$nGYCCmhrzjrgdcxjH$$$$.xLJMTJxaRa12DnhpAJmKQw.NXXZHgyq
    

    2a) What part of this should be stored in the database?
    2b) What data type should be used for the column (MySQL)?

    3) How should one verify a login attempt?

    • Linus Kleen
      Linus Kleen about 13 years
      1.) Read the manual 2. & 3. are questions for themselves.
  • Matt
    Matt about 13 years
    Note, the above shouldn't be used for a login to protect sensitive data. For that, as a minimum, use a different salt for each user and store the salt value in a separate database (accessible only by a different MySQL user) with a table mapping the username to the salt.
  • Admin
    Admin about 13 years
    My CRYPT_SALT_LENGTH is 123, so your substr() line returnes an empty string. What's up with that?
  • Admin
    Admin about 13 years
    I've used $hash = substr($hash, strlen($salt)); or $hash = str_replace($salt, '', $hash);. (They return the same.) Seems to work. It seems the final blowfish hash is 20 letters long, so CHAR(20) might be a proper datatype?
  • user3391801
    user3391801 about 13 years
    The answer above is just plain wrong. In crypt(), you store the entire result of crypt() and feed it back into itself later for validation...
  • user3391801
    user3391801 about 13 years
    chargen.matasano.com/chargen/2007/9/7/… is another excellent resource.
  • Xeoncross
    Xeoncross about 12 years
    @TML, is right - this answer is bad advice. The salt should be unique for each hash and is stored as a suffix to the hash by crypt() automatically.
  • rjha94
    rjha94 almost 12 years
    Having a "fixed" salt is bad idea. The whole purpose of salt is to add "random" bits to an otherwise guessable (e.g. 12345678) password. The chances of attack against stored passwords succeeding with a fixed salt is higher.
  • Neven Boyanov
    Neven Boyanov over 11 years
    What is the reason to use a random salt for every crypt() if you're going to store that salt in the database, as part of the encrypted password? If your database security is compromised and the intruder has access to that table and can read the "encrypted" password fields, then they have plain access to your "super-secret" and randomly generated salt. Although every-time-random salt may make your crypt() work differently every time, your security will not be increased.
  • Neven Boyanov
    Neven Boyanov over 11 years
    My comment above is not entirely correct. Storing the salt along with the hash will protect you against rainbow-tables look up - because there will be different hashes for the same password, but it will not protect you against brute-force or password-dictionaries. Ex.: if I have access to all the salts and hashes I will be able to check who has a password 'test' or '1234', etc. - isn't that true?
  • Luke
    Luke about 10 years
    Rather than PHPass I'm more inclined to used the built in functions provided by PHP. I believe from what I have read, that PHP automatically generates a salt when using the password_hash() function If omitted, a random salt will be generated by password_hash() for each password hashed. This is the intended mode of operation. uk1.php.net/password_hash
  • xyphoid
    xyphoid about 10 years
    Yes, since this post was written, PHP added password_hash - that is a better option than phpass now.