‪TYPO3CMS  ‪main
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 
64  public function ‪getHashedPassword(string $password): ?string
65  {
66  $saltedPW = null;
67  if (!empty($password)) {
68  $salt = $this->‪getGeneratedSalt();
69  $saltedPW = crypt($password, $this->‪applySettingsToSalt($salt));
70  }
71  return $saltedPW;
72  }
73 
84  public function ‪isHashUpdateNeeded(string $passString): bool
85  {
86  return false;
87  }
88 
95  public function ‪isValidSaltedPW(string $saltedPW): bool
96  {
97  $isValid = !strncmp(self::PREFIX, $saltedPW, strlen(self::PREFIX));
98  if ($isValid) {
99  $isValid = $this->‪isValidSalt($saltedPW);
100  }
101  return $isValid;
102  }
103 
115  protected function ‪getGeneratedSalt(): string
116  {
117  $randomBytes = GeneralUtility::makeInstance(Random::class)->generateRandomBytes(6);
118  return $this->‪base64Encode($randomBytes, 6);
119  }
120 
127  protected function ‪applySettingsToSalt(string $salt): string
128  {
129  $saltWithSettings = $salt;
130  $reqLenBase64 = $this->‪getLengthBase64FromBytes(6);
131  // Salt without setting
132  if (strlen($salt) == $reqLenBase64) {
133  $saltWithSettings = self::PREFIX . $salt . '$';
134  }
135  return $saltWithSettings;
136  }
137 
143  protected function ‪getItoa64(): string
144  {
145  return './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
146  }
147 
154  protected function ‪isValidSalt(string $salt): bool
155  {
156  $isValid = ($skip = false);
157  $reqLenBase64 = $this->‪getLengthBase64FromBytes(6);
158  if (strlen($salt) >= $reqLenBase64) {
159  // Salt with prefixed setting
160  if (!strncmp('$', $salt, 1)) {
161  if (!strncmp(self::PREFIX, $salt, strlen(self::PREFIX))) {
162  $isValid = true;
163  $salt = substr($salt, strlen(self::PREFIX));
164  } else {
165  $skip = true;
166  }
167  }
168  // Checking base64 characters
169  if (!$skip && strlen($salt) >= $reqLenBase64) {
170  if (preg_match('/^[' . preg_quote($this->‪getItoa64(), '/') . ']{' . $reqLenBase64 . ',' . $reqLenBase64 . '}$/', substr($salt, 0, $reqLenBase64))) {
171  $isValid = true;
172  }
173  }
174  }
175  return $isValid;
176  }
177 
185  protected function ‪base64Encode(string $input, int $count): string
186  {
187  ‪$output = '';
188  $i = 0;
189  $itoa64 = $this->‪getItoa64();
190  do {
191  $value = ord($input[$i++]);
192  ‪$output .= $itoa64[$value & 63];
193  if ($i < $count) {
194  $value |= ord($input[$i]) << 8;
195  }
196  ‪$output .= $itoa64[$value >> 6 & 63];
197  if ($i++ >= $count) {
198  break;
199  }
200  if ($i < $count) {
201  $value |= ord($input[$i]) << 16;
202  }
203  ‪$output .= $itoa64[$value >> 12 & 63];
204  if ($i++ >= $count) {
205  break;
206  }
207  ‪$output .= $itoa64[$value >> 18 & 63];
208  } while ($i < $count);
209  return ‪$output;
210  }
211 
219  protected function ‪getLengthBase64FromBytes(int $byteLength): int
220  {
221  // Calculates bytes in bits in base64
222  return (int)ceil($byteLength * 8 / 6);
223  }
224 }
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Md5PasswordHash\isValidSalt
‪bool isValidSalt(string $salt)
Definition: Md5PasswordHash.php:154
‪TYPO3\CMS\Core\Crypto\PasswordHashing
Definition: AbstractArgon2PasswordHash.php:18
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Md5PasswordHash\applySettingsToSalt
‪string applySettingsToSalt(string $salt)
Definition: Md5PasswordHash.php:127
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Md5PasswordHash
Definition: Md5PasswordHash.php:31
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Md5PasswordHash\getGeneratedSalt
‪string getGeneratedSalt()
Definition: Md5PasswordHash.php:115
‪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:84
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Md5PasswordHash\isAvailable
‪bool isAvailable()
Definition: Md5PasswordHash.php:59
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Md5PasswordHash\getHashedPassword
‪getHashedPassword(string $password)
Definition: Md5PasswordHash.php:64
‪$output
‪$output
Definition: annotationChecker.php:114
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Md5PasswordHash\base64Encode
‪string base64Encode(string $input, int $count)
Definition: Md5PasswordHash.php:185
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Md5PasswordHash\getItoa64
‪string getItoa64()
Definition: Md5PasswordHash.php:143
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Md5PasswordHash\getLengthBase64FromBytes
‪int getLengthBase64FromBytes(int $byteLength)
Definition: Md5PasswordHash.php:219
‪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:27
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Core\Crypto\PasswordHashing\Md5PasswordHash\isValidSaltedPW
‪bool isValidSaltedPW(string $saltedPW)
Definition: Md5PasswordHash.php:95
‪TYPO3\CMS\Core\Crypto\PasswordHashing\PasswordHashInterface
Definition: PasswordHashInterface.php:25