‪TYPO3CMS  9.5
Argon2iPasswordHash.php
Go to the documentation of this file.
1 <?php
2 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 
29 {
33  protected const ‪PREFIX = '$argon2i$';
34 
47  protected ‪$options = [
48  'memory_cost' => 65536,
49  'time_cost' => 16
50  ];
51 
58  public function ‪__construct(array ‪$options = [])
59  {
60  $newOptions = ‪$this->options;
61  if (isset(‪$options['memory_cost'])) {
62  if ((int)‪$options['memory_cost'] < PASSWORD_ARGON2_DEFAULT_MEMORY_COST) {
63  throw new \InvalidArgumentException(
64  'memory_cost must not be lower than ' . PASSWORD_ARGON2_DEFAULT_MEMORY_COST,
65  1533899612
66  );
67  }
68  $newOptions['memory_cost'] = (int)‪$options['memory_cost'];
69  }
70  if (isset(‪$options['time_cost'])) {
71  if ((int)‪$options['time_cost'] < PASSWORD_ARGON2_DEFAULT_TIME_COST) {
72  throw new \InvalidArgumentException(
73  'time_cost must not be lower than ' . PASSWORD_ARGON2_DEFAULT_TIME_COST,
74  1533899613
75  );
76  }
77  $newOptions['time_cost'] = (int)‪$options['time_cost'];
78  }
79  if (isset(‪$options['threads'])) {
80  if ((int)‪$options['threads'] < PASSWORD_ARGON2_DEFAULT_THREADS) {
81  throw new \InvalidArgumentException(
82  'threads must not be lower than ' . PASSWORD_ARGON2_DEFAULT_THREADS,
83  1533899614
84  );
85  }
86  $newOptions['threads'] = (int)‪$options['threads'];
87  }
88  $this->options = $newOptions;
89  }
90 
99  public function ‪checkPassword(string $plainPW, string $saltedHashPW): bool
100  {
101  return password_verify($plainPW, $saltedHashPW);
102  }
103 
110  public function ‪isAvailable(): bool
111  {
112  return defined('PASSWORD_ARGON2I') && PASSWORD_ARGON2I;
113  }
114 
122  public function ‪getHashedPassword(string $password, string $salt = null)
123  {
124  if ($salt !== null) {
125  trigger_error(static::class . ': using a custom salt is deprecated in PHP password api and ignored.', E_USER_DEPRECATED);
126  }
127  $hashedPassword = null;
128  if ($password !== '') {
129  $hashedPassword = password_hash($password, PASSWORD_ARGON2I, $this->options);
130  if (!is_string($hashedPassword) || empty($hashedPassword)) {
131  throw new InvalidPasswordHashException('Cannot generate password, probably invalid options', 1526052118);
132  }
133  }
134  return $hashedPassword;
135  }
136 
144  public function ‪isHashUpdateNeeded(string $passString): bool
145  {
146  return password_needs_rehash($passString, PASSWORD_ARGON2I, $this->options);
147  }
148 
155  public function ‪isValidSaltedPW(string $saltedPW): bool
156  {
157  $result = false;
158  $passwordInfo = password_get_info($saltedPW);
159  if (isset($passwordInfo['algo'])
160  && $passwordInfo['algo'] === PASSWORD_ARGON2I
161  && strncmp($saltedPW, static::PREFIX, strlen(static::PREFIX)) === 0
162  ) {
163  $result = true;
164  }
165  return $result;
166  }
167 
172  public function ‪getOptions(): array
173  {
174  trigger_error('This method will be removed in TYPO3 v10.0.', E_USER_DEPRECATED);
175  return ‪$this->options;
176  }
177 
184  public function ‪setOptions(array ‪$options): void
185  {
186  trigger_error('This method will be removed in TYPO3 v10.0.', E_USER_DEPRECATED);
187  $newOptions = [];
188 
189  // Check options for validity, else use hard coded defaults
190  if (isset(‪$options['memory_cost'])) {
191  if ((int)‪$options['memory_cost'] < PASSWORD_ARGON2_DEFAULT_MEMORY_COST) {
192  throw new \InvalidArgumentException(
193  'memory_cost must not be lower than ' . PASSWORD_ARGON2_DEFAULT_MEMORY_COST,
194  1526042080
195  );
196  }
197  $newOptions['memory_cost'] = (int)‪$options['memory_cost'];
198  } else {
199  $newOptions['memory_cost'] = 16384;
200  }
201 
202  if (isset(‪$options['time_cost'])) {
203  if ((int)‪$options['time_cost'] < PASSWORD_ARGON2_DEFAULT_TIME_COST) {
204  throw new \InvalidArgumentException(
205  'time_cost must not be lower than ' . PASSWORD_ARGON2_DEFAULT_TIME_COST,
206  1526042081
207  );
208  }
209  $newOptions['time_cost'] = (int)‪$options['time_cost'];
210  } else {
211  $newOptions['time_cost'] = 16;
212  }
213 
214  if (isset(‪$options['threads'])) {
215  if ((int)‪$options['threads'] < PASSWORD_ARGON2_DEFAULT_THREADS) {
216  throw new \InvalidArgumentException(
217  'threads must not be lower than ' . PASSWORD_ARGON2_DEFAULT_THREADS,
218  1526042082
219  );
220  }
221  $newOptions['threads'] = (int)‪$options['threads'];
222  } else {
223  $newOptions['threads'] = 2;
224  }
225 
226  $this->options = $newOptions;
227  }
228 }
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Argon2iPasswordHash\PREFIX
‪const PREFIX
Definition: Argon2iPasswordHash.php:33
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Argon2iPasswordHash\__construct
‪__construct(array $options=[])
Definition: Argon2iPasswordHash.php:57
‪TYPO3\CMS\Core\Crypto\PasswordHashing
Definition: AbstractComposedSalt.php:3
‪TYPO3\CMS\Core\Crypto\PasswordHashing\InvalidPasswordHashException
Definition: InvalidPasswordHashException.php:22
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Argon2iPasswordHash\getHashedPassword
‪string null getHashedPassword(string $password, string $salt=null)
Definition: Argon2iPasswordHash.php:121
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Argon2iPasswordHash\isValidSaltedPW
‪bool isValidSaltedPW(string $saltedPW)
Definition: Argon2iPasswordHash.php:154
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Argon2iPasswordHash\getOptions
‪array getOptions()
Definition: Argon2iPasswordHash.php:171
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Argon2iPasswordHash\isAvailable
‪bool isAvailable()
Definition: Argon2iPasswordHash.php:109
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Argon2iPasswordHash\isHashUpdateNeeded
‪bool isHashUpdateNeeded(string $passString)
Definition: Argon2iPasswordHash.php:143
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Argon2iPasswordHash\checkPassword
‪bool checkPassword(string $plainPW, string $saltedHashPW)
Definition: Argon2iPasswordHash.php:98
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Argon2iPasswordHash\setOptions
‪setOptions(array $options)
Definition: Argon2iPasswordHash.php:183
‪TYPO3\CMS\Core\Crypto\PasswordHashing\PasswordHashInterface
Definition: PasswordHashInterface.php:23
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Argon2iPasswordHash
Definition: Argon2iPasswordHash.php:29
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Argon2iPasswordHash\$options
‪array $options
Definition: Argon2iPasswordHash.php:46