‪TYPO3CMS  10.4
Md5PasswordHash.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 
22 
31 {
35  protected const ‪PREFIX = '$1$';
36 
45  public function ‪checkPassword(string $plainPW, string $saltedHashPW): bool
46  {
47  $isCorrect = false;
48  if ($this->‪isValidSalt($saltedHashPW)) {
49  $isCorrect = \password_verify($plainPW, $saltedHashPW);
50  }
51  return $isCorrect;
52  }
53 
59  public function ‪isAvailable(): bool
60  {
61  return (bool)CRYPT_MD5;
62  }
63 
70  public function ‪getHashedPassword(string $password)
71  {
72  $saltedPW = null;
73  if (!empty($password)) {
74  $salt = $this->‪getGeneratedSalt();
75  $saltedPW = crypt($password, $this->‪applySettingsToSalt($salt));
76  }
77  return $saltedPW;
78  }
79 
90  public function ‪isHashUpdateNeeded(string $passString): bool
91  {
92  return false;
93  }
94 
101  public function ‪isValidSaltedPW(string $saltedPW): bool
102  {
103  $isValid = !strncmp(self::PREFIX, $saltedPW, strlen(self::PREFIX));
104  if ($isValid) {
105  $isValid = $this->‪isValidSalt($saltedPW);
106  }
107  return $isValid;
108  }
109 
121  protected function ‪getGeneratedSalt(): string
122  {
123  $randomBytes = GeneralUtility::makeInstance(Random::class)->generateRandomBytes(6);
124  return $this->‪base64Encode($randomBytes, 6);
125  }
126 
133  protected function ‪applySettingsToSalt(string $salt): string
134  {
135  $saltWithSettings = $salt;
136  $reqLenBase64 = $this->‪getLengthBase64FromBytes(6);
137  // Salt without setting
138  if (strlen($salt) == $reqLenBase64) {
139  $saltWithSettings = self::PREFIX . $salt . '$';
140  }
141  return $saltWithSettings;
142  }
143 
149  protected function ‪getItoa64(): string
150  {
151  return './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
152  }
153 
160  protected function ‪isValidSalt(string $salt): bool
161  {
162  $isValid = ($skip = false);
163  $reqLenBase64 = $this->‪getLengthBase64FromBytes(6);
164  if (strlen($salt) >= $reqLenBase64) {
165  // Salt with prefixed setting
166  if (!strncmp('$', $salt, 1)) {
167  if (!strncmp(self::PREFIX, $salt, strlen(self::PREFIX))) {
168  $isValid = true;
169  $salt = substr($salt, strlen(self::PREFIX));
170  } else {
171  $skip = true;
172  }
173  }
174  // Checking base64 characters
175  if (!$skip && strlen($salt) >= $reqLenBase64) {
176  if (preg_match('/^[' . preg_quote($this->‪getItoa64(), '/') . ']{' . $reqLenBase64 . ',' . $reqLenBase64 . '}$/', substr($salt, 0, $reqLenBase64))) {
177  $isValid = true;
178  }
179  }
180  }
181  return $isValid;
182  }
183 
191  protected function ‪base64Encode(string $input, int $count): string
192  {
193  ‪$output = '';
194  $i = 0;
195  $itoa64 = $this->‪getItoa64();
196  do {
197  $value = ord($input[$i++]);
198  ‪$output .= $itoa64[$value & 63];
199  if ($i < $count) {
200  $value |= ord($input[$i]) << 8;
201  }
202  ‪$output .= $itoa64[$value >> 6 & 63];
203  if ($i++ >= $count) {
204  break;
205  }
206  if ($i < $count) {
207  $value |= ord($input[$i]) << 16;
208  }
209  ‪$output .= $itoa64[$value >> 12 & 63];
210  if ($i++ >= $count) {
211  break;
212  }
213  ‪$output .= $itoa64[$value >> 18 & 63];
214  } while ($i < $count);
215  return ‪$output;
216  }
217 
225  protected function ‪getLengthBase64FromBytes(int $byteLength): int
226  {
227  // Calculates bytes in bits in base64
228  return (int)ceil($byteLength * 8 / 6);
229  }
230 }
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Md5PasswordHash\getHashedPassword
‪string getHashedPassword(string $password)
Definition: Md5PasswordHash.php:70
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Md5PasswordHash\isValidSalt
‪bool isValidSalt(string $salt)
Definition: Md5PasswordHash.php:160
‪TYPO3\CMS\Core\Crypto\PasswordHashing
Definition: AbstractArgon2PasswordHash.php:18
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Md5PasswordHash\applySettingsToSalt
‪string applySettingsToSalt(string $salt)
Definition: Md5PasswordHash.php:133
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Md5PasswordHash
Definition: Md5PasswordHash.php:31
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Md5PasswordHash\getGeneratedSalt
‪string getGeneratedSalt()
Definition: Md5PasswordHash.php:121
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Md5PasswordHash\PREFIX
‪const PREFIX
Definition: Md5PasswordHash.php:35
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Md5PasswordHash\isHashUpdateNeeded
‪bool isHashUpdateNeeded(string $passString)
Definition: Md5PasswordHash.php:90
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Md5PasswordHash\isAvailable
‪bool isAvailable()
Definition: Md5PasswordHash.php:59
‪$output
‪$output
Definition: annotationChecker.php:119
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Md5PasswordHash\base64Encode
‪string base64Encode(string $input, int $count)
Definition: Md5PasswordHash.php:191
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Md5PasswordHash\getItoa64
‪string getItoa64()
Definition: Md5PasswordHash.php:149
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Md5PasswordHash\getLengthBase64FromBytes
‪int getLengthBase64FromBytes(int $byteLength)
Definition: Md5PasswordHash.php:225
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Md5PasswordHash\checkPassword
‪bool checkPassword(string $plainPW, string $saltedHashPW)
Definition: Md5PasswordHash.php:45
‪TYPO3\CMS\Core\Crypto\Random
Definition: Random.php:24
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:46
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Md5PasswordHash\isValidSaltedPW
‪bool isValidSaltedPW(string $saltedPW)
Definition: Md5PasswordHash.php:101
‪TYPO3\CMS\Core\Crypto\PasswordHashing\PasswordHashInterface
Definition: PasswordHashInterface.php:25