title: Am I using PHP's crypt() function correctly?
body: <p>I've been using PHP's <code>crypt()</code> as a way to store and verify passwords in my database. I use hashing for other things, but <code>crypt()</code> for passwords. The documentation isn't that good and there seems to be a lot of debate. I'm using blowfish and two salts to crypt a password and store it in the database. Before I would store the salt and the encrypted password, (like a salted hash) but realized its redundant because the salt is part of the encrypted password string.</p>
  
  <p>I'm a little confused on how rainbow table attacks would work on <code>crypt()</code>, anyway does this look correct from a security standpoint. I use a second salt to append to the password to increase the entropy of short passwords, probably overkill but why not?</p>
  
  <pre><code>function crypt_password($password) {
  if ($password) {
      //find the longest valid salt allowed by server
      $max_salt = CRYPT_SALT_LENGTH;
  
      //blowfish hashing with a salt as follows: "$2a$", a two digit cost parameter, "$", and 22 base 64
      $blowfish = '$2a$10$';
  
      //get the longest salt, could set to 22 crypt ignores extra data
      $salt = get_salt ( $max_salt );
  
      //get a second salt to strengthen password
      $salt2 = get_salt ( 30 ); //set to whatever
  
  
      //append salt2 data to the password, and crypt using salt, results in a 60 char output
      $crypt_pass = crypt ( $password . $salt2, $blowfish . $salt );
  
      //insert crypt pass along with salt2 into database.
      $sql = "insert into database....";
  
      return true;
      }
  }  
  
  
  function get_salt($length) {
  $options = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789./';
  
  $salt = '';
  
  for($i = 0; $i &lt;= $length; $i ++) {
      $options = str_shuffle ( $options );
      $salt .= $options [rand ( 0, 63 )];
  }
  return $salt;
  }
  
  function verify_password($input_password)
  {
  if($input_password)
  {
      //get stored crypt pass,and salt2 from the database
      $stored_password = 'somethingfromdatabase';
      $stored_salt2 = 'somethingelsefromdatabase';
  
      //compare the crypt of input+stored_salt2 to the stored crypt password
      if (crypt($input_password . $stored_salt2, $stored_password) == $stored_password) {
          //authenticated
          return true;
      }
      else return false;
  }
  else return false;
  }
  </code></pre>