‪TYPO3CMS  9.5
Md5PasswordHash.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 
21 
30 {
32 
36  private ‪$deprecatedPublicMethods = [
37  'isValidSalt' => 'Using Md5PasswordHash::isValidSalt() is deprecated and will not be possible anymore in TYPO3 v10.0.',
38  'base64Encode' => 'Using Md5PasswordHash::base64Encode() is deprecated and will not be possible anymore in TYPO3 v10.0.',
39  ];
40 
44  protected const ‪PREFIX = '$1$';
45 
52  const ‪ITOA64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
53 
62  public function ‪checkPassword(string $plainPW, string $saltedHashPW): bool
63  {
64  $isCorrect = false;
65  if ($this->‪isValidSalt($saltedHashPW)) {
66  $isCorrect = \password_verify($plainPW, $saltedHashPW);
67  }
68  return $isCorrect;
69  }
70 
76  public function ‪isAvailable(): bool
77  {
78  return (bool)CRYPT_MD5;
79  }
80 
88  public function ‪getHashedPassword(string $password, string $salt = null)
89  {
90  if ($salt !== null) {
91  trigger_error(static::class . ': using a custom salt is deprecated.', E_USER_DEPRECATED);
92  }
93  $saltedPW = null;
94  if (!empty($password)) {
95  if (empty($salt) || !$this->‪isValidSalt($salt)) {
96  $salt = $this->‪getGeneratedSalt();
97  }
98  $saltedPW = crypt($password, $this->‪applySettingsToSalt($salt));
99  }
100  return $saltedPW;
101  }
102 
113  public function ‪isHashUpdateNeeded(string $passString): bool
114  {
115  return false;
116  }
117 
124  public function ‪isValidSaltedPW(string $saltedPW): bool
125  {
126  $isValid = !strncmp(self::PREFIX, $saltedPW, strlen(self::PREFIX));
127  if ($isValid) {
128  $isValid = $this->‪isValidSalt($saltedPW);
129  }
130  return $isValid;
131  }
132 
144  protected function ‪getGeneratedSalt(): string
145  {
146  $randomBytes = GeneralUtility::makeInstance(Random::class)->generateRandomBytes(6);
147  return $this->‪base64Encode($randomBytes, 6);
148  }
149 
156  protected function ‪applySettingsToSalt(string $salt): string
157  {
158  $saltWithSettings = $salt;
159  $reqLenBase64 = $this->‪getLengthBase64FromBytes(6);
160  // Salt without setting
161  if (strlen($salt) == $reqLenBase64) {
162  $saltWithSettings = self::PREFIX . $salt . '$';
163  }
164  return $saltWithSettings;
165  }
166 
172  protected function ‪getItoa64(): string
173  {
174  return './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
175  }
176 
183  protected function ‪isValidSalt(string $salt): bool
184  {
185  $isValid = ($skip = false);
186  $reqLenBase64 = $this->‪getLengthBase64FromBytes(6);
187  if (strlen($salt) >= $reqLenBase64) {
188  // Salt with prefixed setting
189  if (!strncmp('$', $salt, 1)) {
190  if (!strncmp(self::PREFIX, $salt, strlen(self::PREFIX))) {
191  $isValid = true;
192  $salt = substr($salt, strlen(self::PREFIX));
193  } else {
194  $skip = true;
195  }
196  }
197  // Checking base64 characters
198  if (!$skip && strlen($salt) >= $reqLenBase64) {
199  if (preg_match('/^[' . preg_quote($this->‪getItoa64(), '/') . ']{' . $reqLenBase64 . ',' . $reqLenBase64 . '}$/', substr($salt, 0, $reqLenBase64))) {
200  $isValid = true;
201  }
202  }
203  }
204  return $isValid;
205  }
206 
214  protected function ‪base64Encode(string $input, int $count): string
215  {
216  ‪$output = '';
217  $i = 0;
218  $itoa64 = $this->‪getItoa64();
219  do {
220  $value = ord($input[$i++]);
221  ‪$output .= $itoa64[$value & 63];
222  if ($i < $count) {
223  $value |= ord($input[$i]) << 8;
224  }
225  ‪$output .= $itoa64[$value >> 6 & 63];
226  if ($i++ >= $count) {
227  break;
228  }
229  if ($i < $count) {
230  $value |= ord($input[$i]) << 16;
231  }
232  ‪$output .= $itoa64[$value >> 12 & 63];
233  if ($i++ >= $count) {
234  break;
235  }
236  ‪$output .= $itoa64[$value >> 18 & 63];
237  } while ($i < $count);
238  return ‪$output;
239  }
240 
248  protected function ‪getLengthBase64FromBytes(int $byteLength): int
249  {
250  // Calculates bytes in bits in base64
251  return (int)ceil($byteLength * 8 / 6);
252  }
253 
260  public function ‪getSetting(): string
261  {
262  trigger_error('This method will be removed in TYPO3 v10.0.', E_USER_DEPRECATED);
263  return ‪self::PREFIX;
264  }
265 
272  public function ‪getSaltLength(): int
273  {
274  trigger_error('This method will be removed in TYPO3 v10.0.', E_USER_DEPRECATED);
275  return 6;
276  }
277 }
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Md5PasswordHash\getSaltLength
‪int getSaltLength()
Definition: Md5PasswordHash.php:271
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Md5PasswordHash\ITOA64
‪const ITOA64
Definition: Md5PasswordHash.php:51
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Md5PasswordHash\getSetting
‪string getSetting()
Definition: Md5PasswordHash.php:259
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Md5PasswordHash\isValidSalt
‪bool isValidSalt(string $salt)
Definition: Md5PasswordHash.php:182
‪TYPO3\CMS\Core\Crypto\PasswordHashing
Definition: AbstractComposedSalt.php:3
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Md5PasswordHash\applySettingsToSalt
‪string applySettingsToSalt(string $salt)
Definition: Md5PasswordHash.php:155
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Md5PasswordHash
Definition: Md5PasswordHash.php:30
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Md5PasswordHash\getGeneratedSalt
‪string getGeneratedSalt()
Definition: Md5PasswordHash.php:143
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Md5PasswordHash\PREFIX
‪const PREFIX
Definition: Md5PasswordHash.php:43
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Md5PasswordHash\isHashUpdateNeeded
‪bool isHashUpdateNeeded(string $passString)
Definition: Md5PasswordHash.php:112
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Md5PasswordHash\isAvailable
‪bool isAvailable()
Definition: Md5PasswordHash.php:75
‪TYPO3\CMS\Core\Compatibility\PublicMethodDeprecationTrait
Definition: PublicMethodDeprecationTrait.php:68
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Md5PasswordHash\$deprecatedPublicMethods
‪array $deprecatedPublicMethods
Definition: Md5PasswordHash.php:35
‪$output
‪$output
Definition: annotationChecker.php:113
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Md5PasswordHash\base64Encode
‪string base64Encode(string $input, int $count)
Definition: Md5PasswordHash.php:213
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Md5PasswordHash\getHashedPassword
‪string getHashedPassword(string $password, string $salt=null)
Definition: Md5PasswordHash.php:87
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Md5PasswordHash\getItoa64
‪string getItoa64()
Definition: Md5PasswordHash.php:171
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Md5PasswordHash\getLengthBase64FromBytes
‪int getLengthBase64FromBytes(int $byteLength)
Definition: Md5PasswordHash.php:247
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Md5PasswordHash\checkPassword
‪bool checkPassword(string $plainPW, string $saltedHashPW)
Definition: Md5PasswordHash.php:61
‪TYPO3\CMS\Core\Crypto\Random
Definition: Random.php:22
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:45
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Md5PasswordHash\isValidSaltedPW
‪bool isValidSaltedPW(string $saltedPW)
Definition: Md5PasswordHash.php:123
‪TYPO3\CMS\Core\Crypto\PasswordHashing\PasswordHashInterface
Definition: PasswordHashInterface.php:23