$value) { switch (strtolower($key)) { case 'salt': $this->setSalt($value); break; case 'cost': $this->setCost($value); break; } } } } /** * Bcrypt * * @param string $password * @throws Exception\RuntimeException * @return string */ public function create($password) { if (empty($this->salt)) { $salt = Rand::getBytes(self::MIN_SALT_SIZE); } else { $salt = $this->salt; } $salt64 = substr(str_replace('+', '.', base64_encode($salt)), 0, 22); /** * Check for security flaw in the bcrypt implementation used by crypt() * @see http://php.net/security/crypt_blowfish.php */ $prefix = '$2y$'; $hash = crypt($password, $prefix . $this->cost . '$' . $salt64); if (strlen($hash) < 13) { throw new Exception\RuntimeException('Error during the bcrypt generation'); } return $hash; } /** * Verify if a password is correct against a hash value * * @param string $password * @param string $hash * @throws Exception\RuntimeException when the hash is unable to be processed * @return bool */ public function verify($password, $hash) { $result = crypt($password, $hash); return Utils::compareStrings($hash, $result); } /** * Set the cost parameter * * @param int|string $cost * @throws Exception\InvalidArgumentException * @return Bcrypt */ public function setCost($cost) { if (!empty($cost)) { $cost = (int) $cost; if ($cost < 4 || $cost > 31) { throw new Exception\InvalidArgumentException( 'The cost parameter of bcrypt must be in range 04-31' ); } $this->cost = sprintf('%1$02d', $cost); } return $this; } /** * Get the cost parameter * * @return string */ public function getCost() { return $this->cost; } /** * Set the salt value * * @param string $salt * @throws Exception\InvalidArgumentException * @return Bcrypt */ public function setSalt($salt) { if (strlen($salt) < self::MIN_SALT_SIZE) { throw new Exception\InvalidArgumentException( 'The length of the salt must be at least ' . self::MIN_SALT_SIZE . ' bytes' ); } $this->salt = $salt; return $this; } /** * Get the salt value * * @return string */ public function getSalt() { return $this->salt; } /** * Set the backward compatibility $2a$ instead of $2y$ for PHP 5.3.7+ * * @deprecated since zf 2.3 requires PHP >= 5.3.23 * @param bool $value * @return Bcrypt */ public function setBackwardCompatibility($value) { return $this; } /** * Get the backward compatibility * * @deprecated since zf 2.3 requires PHP >= 5.3.23 * @return bool */ public function getBackwardCompatibility() { return false; } }