You are here

protected function PhpassHashedPassword::crypt in Drupal 8

Same name and namespace in other branches
  1. 9 core/lib/Drupal/Core/Password/PhpassHashedPassword.php \Drupal\Core\Password\PhpassHashedPassword::crypt()

Hash a password using a secure stretched hash.

By using a salt and repeated hashing the password is "stretched". Its security is increased because it becomes much more computationally costly for an attacker to try to break the hash by brute-force computation of the hashes of a large number of plain-text words or strings to find a match.

Parameters

string $algo: The string name of a hashing algorithm usable by hash(), like 'sha256'.

string $password: Plain-text password up to 512 bytes (128 to 512 UTF-8 characters) to hash.

string $setting: An existing hash or the output of $this->generateSalt(). Must be at least 12 characters (the settings and salt).

Return value

string A string containing the hashed password (and salt) or FALSE on failure. The return string will be truncated at HASH_LENGTH characters max.

2 calls to PhpassHashedPassword::crypt()
PhpassHashedPassword::check in core/lib/Drupal/Core/Password/PhpassHashedPassword.php
Check whether a plain text password matches a hashed password.
PhpassHashedPassword::hash in core/lib/Drupal/Core/Password/PhpassHashedPassword.php
Hash a password using a secure hash.

File

core/lib/Drupal/Core/Password/PhpassHashedPassword.php, line 157

Class

PhpassHashedPassword
Secure password hashing functions based on the Portable PHP password hashing framework.

Namespace

Drupal\Core\Password

Code

protected function crypt($algo, $password, $setting) {

  // Prevent DoS attacks by refusing to hash large passwords.
  if (strlen($password) > PasswordInterface::PASSWORD_MAX_LENGTH) {
    return FALSE;
  }

  // The first 12 characters of an existing hash are its setting string.
  $setting = substr($setting, 0, 12);
  if ($setting[0] != '$' || $setting[2] != '$') {
    return FALSE;
  }
  $count_log2 = $this
    ->getCountLog2($setting);

  // Stored hashes may have been crypted with any iteration count. However we
  // do not allow applying the algorithm for unreasonable low and high values
  // respectively.
  if ($count_log2 != $this
    ->enforceLog2Boundaries($count_log2)) {
    return FALSE;
  }
  $salt = substr($setting, 4, 8);

  // Hashes must have an 8 character salt.
  if (strlen($salt) != 8) {
    return FALSE;
  }

  // Convert the base 2 logarithm into an integer.
  $count = 1 << $count_log2;
  $hash = hash($algo, $salt . $password, TRUE);
  do {
    $hash = hash($algo, $hash . $password, TRUE);
  } while (--$count);
  $len = strlen($hash);
  $output = $setting . $this
    ->base64Encode($hash, $len);

  // $this->base64Encode() of a 16 byte MD5 will always be 22 characters.
  // $this->base64Encode() of a 64 byte sha512 will always be 86 characters.
  $expected = 12 + ceil(8 * $len / 6);
  return strlen($output) == $expected ? substr($output, 0, static::HASH_LENGTH) : FALSE;
}