BasePasswordEncoder.php 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\Security\Core\Encoder;
  11. /**
  12. * BasePasswordEncoder is the base class for all password encoders.
  13. *
  14. * @author Fabien Potencier <fabien@symfony.com>
  15. */
  16. abstract class BasePasswordEncoder implements PasswordEncoderInterface
  17. {
  18. public const MAX_PASSWORD_LENGTH = 4096;
  19. /**
  20. * {@inheritdoc}
  21. */
  22. public function needsRehash(string $encoded): bool
  23. {
  24. return false;
  25. }
  26. /**
  27. * Demerges a merge password and salt string.
  28. *
  29. * @return array An array where the first element is the password and the second the salt
  30. */
  31. protected function demergePasswordAndSalt(string $mergedPasswordSalt)
  32. {
  33. if (empty($mergedPasswordSalt)) {
  34. return ['', ''];
  35. }
  36. $password = $mergedPasswordSalt;
  37. $salt = '';
  38. $saltBegins = strrpos($mergedPasswordSalt, '{');
  39. if (false !== $saltBegins && $saltBegins + 1 < \strlen($mergedPasswordSalt)) {
  40. $salt = substr($mergedPasswordSalt, $saltBegins + 1, -1);
  41. $password = substr($mergedPasswordSalt, 0, $saltBegins);
  42. }
  43. return [$password, $salt];
  44. }
  45. /**
  46. * Merges a password and a salt.
  47. *
  48. * @return string a merged password and salt
  49. *
  50. * @throws \InvalidArgumentException
  51. */
  52. protected function mergePasswordAndSalt(string $password, ?string $salt)
  53. {
  54. if (empty($salt)) {
  55. return $password;
  56. }
  57. if (false !== strrpos($salt, '{') || false !== strrpos($salt, '}')) {
  58. throw new \InvalidArgumentException('Cannot use { or } in salt.');
  59. }
  60. return $password.'{'.$salt.'}';
  61. }
  62. /**
  63. * Compares two passwords.
  64. *
  65. * This method implements a constant-time algorithm to compare passwords to
  66. * avoid (remote) timing attacks.
  67. *
  68. * @return bool true if the two passwords are the same, false otherwise
  69. */
  70. protected function comparePasswords(string $password1, string $password2)
  71. {
  72. return hash_equals($password1, $password2);
  73. }
  74. /**
  75. * Checks if the password is too long.
  76. *
  77. * @return bool true if the password is too long, false otherwise
  78. */
  79. protected function isPasswordTooLong(string $password)
  80. {
  81. return \strlen($password) > static::MAX_PASSWORD_LENGTH;
  82. }
  83. }