Blowfish password encryption

Date: 14 Mar 2012
Author: Erik Dubbelboer

Since 5.3 PHP supports Blowfish hashing. This is commonly seen as the most secure way to hash a password. The main advantage is that the function can be set to be really slow which makes brute forcing useless.

Here’s an example implementation:

<?

class BlowfishPassword {
  const strength = 13; // On our machine this makes it slow but not so slow as to annoy the user (less then 1 second).

  private $hash;

  public function __construct($password, $hash = false) {
    if ($hash !== false) {
      $this->hash = $hash;
    } else {
      $salt = str_random(22, '\.\/0-9A-Za-z'); // Random per password salt.

      $strength = sprintf('%02d', $this::strength); // Always needs to be 2 characters.

      $this->hash = crypt($password, '$2a$' . $strength . '$' . $salt . '$');
    }
  }

  public function equals($password) {
    return ($this->hash === crypt($password, $this->hash));
  }

  public function getHash() {
    return $this->hash;
  }
}

The str_random() function is implemented like this:

<?
function str_random($length, $range = true) {
  $r = '';

  while ($length > 0) {
    $c = chr(rand(32, 126));

    if (($range === true) || (preg_match('/['.$range.']/', $c) == 1)) {
      $r .= $c;
      --$length;
    }
  }

  return $r;
}
comments powered by Disqus