‪TYPO3CMS  ‪main
AbstractArgon2PasswordHash.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
24 {
35  protected ‪$options = [
36  'memory_cost' => 65536,
37  'time_cost' => 16,
38  ];
39 
45  public function ‪__construct(array ‪$options = [])
46  {
47  $newOptions = ‪$this->options;
48  if (isset(‪$options['memory_cost'])) {
49  if ((int)‪$options['memory_cost'] < PASSWORD_ARGON2_DEFAULT_MEMORY_COST) {
50  throw new \InvalidArgumentException(
51  'memory_cost must not be lower than ' . PASSWORD_ARGON2_DEFAULT_MEMORY_COST,
52  1533899612
53  );
54  }
55  $newOptions['memory_cost'] = (int)‪$options['memory_cost'];
56  }
57  if (isset(‪$options['time_cost'])) {
58  if ((int)‪$options['time_cost'] < PASSWORD_ARGON2_DEFAULT_TIME_COST) {
59  throw new \InvalidArgumentException(
60  'time_cost must not be lower than ' . PASSWORD_ARGON2_DEFAULT_TIME_COST,
61  1533899613
62  );
63  }
64  $newOptions['time_cost'] = (int)‪$options['time_cost'];
65  }
66  if (isset(‪$options['threads'])) {
67  if (extension_loaded('sodium')) {
68  // Libsodium does not support threads, so ignore the
69  // options and force single-thread.
70  $newOptions['threads'] = 1;
71  } elseif ((int)‪$options['threads'] < PASSWORD_ARGON2_DEFAULT_THREADS) {
72  throw new \InvalidArgumentException(
73  'threads must not be lower than ' . PASSWORD_ARGON2_DEFAULT_THREADS,
74  1533899614
75  );
76  } else {
77  $newOptions['threads'] = (int)‪$options['threads'];
78  }
79  }
80  $this->options = $newOptions;
81  }
82 
91  protected function ‪getPasswordAlgorithm()
92  {
93  return constant($this->‪getPasswordAlgorithmName());
94  }
95 
104  public function ‪checkPassword(string $plainPW, string $saltedHashPW): bool
105  {
106  return password_verify($plainPW, $saltedHashPW);
107  }
108 
113  public function ‪isAvailable(): bool
114  {
115  return defined($this->‪getPasswordAlgorithmName()) && $this->‪getPasswordAlgorithm();
116  }
117 
118  public function ‪getHashedPassword(string $password): ?string
119  {
120  $hashedPassword = null;
121  if ($password !== '') {
122  $hashedPassword = password_hash($password, $this->‪getPasswordAlgorithm(), $this->options);
123  if (!is_string($hashedPassword) || empty($hashedPassword)) {
124  throw new ‪InvalidPasswordHashException('Cannot generate password, probably invalid options', 1526052118);
125  }
126  }
127  return $hashedPassword;
128  }
129 
137  public function ‪isHashUpdateNeeded(string $passString): bool
138  {
139  return password_needs_rehash($passString, $this->‪getPasswordAlgorithm(), $this->options);
140  }
141 
148  public function ‪isValidSaltedPW(string $saltedPW): bool
149  {
150  $passwordInfo = password_get_info($saltedPW);
151 
152  return
153  isset($passwordInfo['algo'])
154  && $passwordInfo['algo'] === $this->‪getPasswordAlgorithm()
155  && strncmp($saltedPW, $this->‪getPasswordHashPrefix(), strlen($this->‪getPasswordHashPrefix())) === 0;
156  }
157 }
‪TYPO3\CMS\Core\Crypto\PasswordHashing\AbstractArgon2PasswordHash\isAvailable
‪isAvailable()
Definition: AbstractArgon2PasswordHash.php:112
‪TYPO3\CMS\Core\Crypto\PasswordHashing\AbstractArgon2PasswordHash\checkPassword
‪bool checkPassword(string $plainPW, string $saltedHashPW)
Definition: AbstractArgon2PasswordHash.php:103
‪TYPO3\CMS\Core\Crypto\PasswordHashing\AbstractArgon2PasswordHash\isHashUpdateNeeded
‪bool isHashUpdateNeeded(string $passString)
Definition: AbstractArgon2PasswordHash.php:136
‪TYPO3\CMS\Core\Crypto\PasswordHashing\AbstractArgon2PasswordHash\__construct
‪__construct(array $options=[])
Definition: AbstractArgon2PasswordHash.php:44
‪TYPO3\CMS\Core\Crypto\PasswordHashing
Definition: AbstractArgon2PasswordHash.php:18
‪TYPO3\CMS\Core\Crypto\PasswordHashing\InvalidPasswordHashException
Definition: InvalidPasswordHashException.php:25
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Argon2PasswordHashInterface\getPasswordHashPrefix
‪getPasswordHashPrefix()
‪TYPO3\CMS\Core\Crypto\PasswordHashing\AbstractArgon2PasswordHash
Definition: AbstractArgon2PasswordHash.php:24
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Argon2PasswordHashInterface\getPasswordAlgorithmName
‪getPasswordAlgorithmName()
‪TYPO3\CMS\Core\Crypto\PasswordHashing\AbstractArgon2PasswordHash\getPasswordAlgorithm
‪int string null getPasswordAlgorithm()
Definition: AbstractArgon2PasswordHash.php:90
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Argon2PasswordHashInterface
Definition: Argon2PasswordHashInterface.php:21
‪TYPO3\CMS\Core\Crypto\PasswordHashing\AbstractArgon2PasswordHash\isValidSaltedPW
‪bool isValidSaltedPW(string $saltedPW)
Definition: AbstractArgon2PasswordHash.php:147
‪TYPO3\CMS\Core\Crypto\PasswordHashing\AbstractArgon2PasswordHash\getHashedPassword
‪getHashedPassword(string $password)
Definition: AbstractArgon2PasswordHash.php:117
‪TYPO3\CMS\Core\Crypto\PasswordHashing\PasswordHashInterface
Definition: PasswordHashInterface.php:25
‪TYPO3\CMS\Core\Crypto\PasswordHashing\AbstractArgon2PasswordHash\$options
‪array $options
Definition: AbstractArgon2PasswordHash.php:34