ILIAS  release_8 Revision v8.19
All Data Structures Namespaces Files Functions Variables Modules Pages
ilBcryptPasswordEncoder Class Reference
+ Inheritance diagram for ilBcryptPasswordEncoder:
+ Collaboration diagram for ilBcryptPasswordEncoder:

Public Member Functions

 __construct (array $config=[])
 
 getDataDirectory ()
 
 setDataDirectory (string $data_directory)
 
 isBackwardCompatibilityEnabled ()
 
 setBackwardCompatibility (bool $backward_compatibility)
 Set the backward compatibility $2a$ instead of $2y$ for PHP 5.3.7+. More...
 
 isSecurityFlawIgnored ()
 
 setIsSecurityFlawIgnored (bool $is_security_flaw_ignored)
 
 getClientSalt ()
 
 setClientSalt (?string $client_salt)
 
 encodePassword (string $raw, string $salt)
 Encodes the raw password. More...
 
 isPasswordValid (string $encoded, string $raw, string $salt)
 Checks a raw password against an encoded password. More...
 
 getName ()
 Returns a unique name/id of the concrete password encoder. More...
 
 requiresSalt ()
 Returns whether the encoder requires a salt. More...
 
 requiresReencoding (string $encoded)
 Returns whether the encoded password needs to be re-encoded. More...
 
 getClientSaltLocation ()
 
- Public Member Functions inherited from ilBcryptPhpPasswordEncoder
 __construct (array $config=[])
 
 benchmarkCost (float $time_target=0.05)
 
 getName ()
 Returns a unique name/id of the concrete password encoder. More...
 
 getCosts ()
 
 setCosts (string $costs)
 
 encodePassword (string $raw, string $salt)
 Encodes the raw password. More...
 
 isPasswordValid (string $encoded, string $raw, string $salt)
 Checks a raw password against an encoded password. More...
 
 requiresReencoding (string $encoded)
 Returns whether the encoded password needs to be re-encoded. More...
 
- Public Member Functions inherited from ilBasePasswordEncoder
 isSupportedByRuntime ()
 Returns whether the encoder is supported by the runtime (PHP, HHVM, ...) More...
 
 requiresSalt ()
 Returns whether the encoder requires a salt. More...
 
 requiresReencoding (string $encoded)
 Returns whether the encoded password needs to be re-encoded. More...
 

Data Fields

const SALT_STORAGE_FILENAME = 'pwsalt.txt'
 

Protected Member Functions

 init ()
 
 isBcryptSupported ()
 
 encode (string $raw, string $userSecret)
 
 check (string $encoded, string $raw, string $salt)
 
- Protected Member Functions inherited from ilBcryptPhpPasswordEncoder
 init ()
 
- Protected Member Functions inherited from ilBasePasswordEncoder
 comparePasswords (string $knownString, string $userString)
 Compares two passwords. More...
 
 isPasswordTooLong (string $password)
 

Private Member Functions

 readClientSalt ()
 
 generateClientSalt ()
 
 storeClientSalt ()
 

Private Attributes

const MIN_SALT_SIZE = 16
 
string $client_salt = null
 
bool $is_security_flaw_ignored = false
 
bool $backward_compatibility = false
 
string $data_directory = ''
 

Additional Inherited Members

- Protected Attributes inherited from ilBcryptPhpPasswordEncoder
string $costs = '08'
 

Detailed Description

Definition at line 27 of file class.ilBcryptPasswordEncoder.php.

Constructor & Destructor Documentation

◆ __construct()

ilBcryptPasswordEncoder::__construct ( array  $config = [])
Parameters
array<string,mixed>$config
Exceptions
ilPasswordException

Definition at line 44 of file class.ilBcryptPasswordEncoder.php.

References $config, ILIAS\LTI\ToolProvider\$key, ILIAS\GlobalScreen\Provider\__construct(), setDataDirectory(), and setIsSecurityFlawIgnored().

45  {
46  foreach ($config as $key => $value) {
47  $key = strtolower($key);
48  if ($key === 'ignore_security_flaw') {
49  $this->setIsSecurityFlawIgnored($value);
50  } elseif ($key === 'data_directory') {
51  $this->setDataDirectory($value);
52  }
53  }
54 
56  }
if(!array_key_exists('PATH_INFO', $_SERVER)) $config
Definition: metadata.php:85
setIsSecurityFlawIgnored(bool $is_security_flaw_ignored)
setDataDirectory(string $data_directory)
string $key
Consumer key/client ID value.
Definition: System.php:193
__construct(Container $dic, ilPlugin $plugin)
+ Here is the call graph for this function:

Member Function Documentation

◆ check()

ilBcryptPasswordEncoder::check ( string  $encoded,
string  $raw,
string  $salt 
)
protected

Definition at line 189 of file class.ilBcryptPasswordEncoder.php.

References ilBasePasswordEncoder\comparePasswords(), and getClientSalt().

Referenced by isPasswordValid().

189  : bool
190  {
191  $hashedPassword = hash_hmac(
192  'whirlpool',
193  str_pad($raw, strlen($raw) * 4, sha1($salt), STR_PAD_BOTH),
194  $this->getClientSalt(),
195  true
196  );
197 
198  return $this->comparePasswords($encoded, crypt($hashedPassword, substr($encoded, 0, 30)));
199  }
comparePasswords(string $knownString, string $userString)
Compares two passwords.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ encode()

ilBcryptPasswordEncoder::encode ( string  $raw,
string  $userSecret 
)
protected

Check for security flaw in the bcrypt implementation used by crypt()

See also
http://php.net/security/crypt_blowfish.php

Definition at line 148 of file class.ilBcryptPasswordEncoder.php.

References getClientSalt(), ilBcryptPhpPasswordEncoder\getCosts(), isBackwardCompatibilityEnabled(), isBcryptSupported(), and isSecurityFlawIgnored().

Referenced by encodePassword().

148  : string
149  {
150  $clientSecret = $this->getClientSalt();
151  $hashedPassword = hash_hmac(
152  'whirlpool',
153  str_pad($raw, strlen($raw) * 4, sha1($userSecret), STR_PAD_BOTH),
154  $clientSecret,
155  true
156  );
157  $salt = substr(
158  str_shuffle(str_repeat('./0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 22)),
159  0,
160  22
161  );
162 
167  if ($this->isBcryptSupported() && !$this->isBackwardCompatibilityEnabled()) {
168  $prefix = '$2y$';
169  } else {
170  $prefix = '$2a$';
171  // check if the password contains 8-bit character
172  if (!$this->isSecurityFlawIgnored() && preg_match('#[\x80-\xFF]#', $raw)) {
173  throw new ilPasswordException(
174  'The bcrypt implementation used by PHP can contain a security flaw ' .
175  'using passwords with 8-bit characters. ' .
176  'We suggest to upgrade to PHP 5.3.7+ or use passwords with only 7-bit characters.'
177  );
178  }
179  }
180 
181  $saltedPassword = crypt($hashedPassword, $prefix . $this->getCosts() . '$' . $salt);
182  if (strlen($saltedPassword) <= 13) {
183  throw new ilPasswordException('Error during the bcrypt generation');
184  }
185 
186  return $saltedPassword;
187  }
Class for user password exception handling in ILIAS.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ encodePassword()

ilBcryptPasswordEncoder::encodePassword ( string  $raw,
string  $salt 
)

Encodes the raw password.

Parameters
string$rawThe password to encode
string$saltThe salt
Returns
string The encoded password

Implements ilPasswordEncoder.

Definition at line 111 of file class.ilBcryptPasswordEncoder.php.

References encode(), getClientSalt(), and ilBasePasswordEncoder\isPasswordTooLong().

Referenced by ilBcryptPasswordEncoderTest\testExceptionIsRaisedIfThePasswordExceedsTheSupportedLengthOnEncoding(), and ilBcryptPasswordEncoderTest\testPasswordShouldBeCorrectlyEncodedAndVerified().

111  : string
112  {
113  if (!$this->getClientSalt()) {
114  throw new ilPasswordException('Missing client salt.');
115  }
116 
117  if ($this->isPasswordTooLong($raw)) {
118  throw new ilPasswordException('Invalid password.');
119  }
120 
121  return $this->encode($raw, $salt);
122  }
encode(string $raw, string $userSecret)
Class for user password exception handling in ILIAS.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ generateClientSalt()

ilBcryptPasswordEncoder::generateClientSalt ( )
private

Definition at line 219 of file class.ilBcryptPasswordEncoder.php.

References ilPasswordUtils\getBytes(), and setClientSalt().

Referenced by readClientSalt().

219  : void
220  {
221  $this->setClientSalt(
222  substr(str_replace('+', '.', base64_encode(ilPasswordUtils::getBytes(self::MIN_SALT_SIZE))), 0, 22)
223  );
224  }
static getBytes(int $length)
Generate random bytes using OpenSSL or Mcrypt and mt_rand() as fallback.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getClientSalt()

ilBcryptPasswordEncoder::getClientSalt ( )

Definition at line 101 of file class.ilBcryptPasswordEncoder.php.

References $client_salt.

Referenced by check(), encode(), encodePassword(), isPasswordValid(), and storeClientSalt().

101  : ?string
102  {
103  return $this->client_salt;
104  }
+ Here is the caller graph for this function:

◆ getClientSaltLocation()

ilBcryptPasswordEncoder::getClientSaltLocation ( )

Definition at line 201 of file class.ilBcryptPasswordEncoder.php.

References getDataDirectory().

Referenced by readClientSalt(), and storeClientSalt().

201  : string
202  {
203  return $this->getDataDirectory() . '/' . self::SALT_STORAGE_FILENAME;
204  }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getDataDirectory()

ilBcryptPasswordEncoder::getDataDirectory ( )

Definition at line 68 of file class.ilBcryptPasswordEncoder.php.

References $data_directory.

Referenced by getClientSaltLocation().

68  : string
69  {
70  return $this->data_directory;
71  }
+ Here is the caller graph for this function:

◆ getName()

ilBcryptPasswordEncoder::getName ( )

Returns a unique name/id of the concrete password encoder.

Implements ilPasswordEncoder.

Definition at line 133 of file class.ilBcryptPasswordEncoder.php.

Referenced by ilBcryptPasswordEncoderTest\testNameShouldBeBcrypt().

133  : string
134  {
135  return 'bcrypt';
136  }
+ Here is the caller graph for this function:

◆ init()

ilBcryptPasswordEncoder::init ( )
protected

Definition at line 58 of file class.ilBcryptPasswordEncoder.php.

References readClientSalt().

58  : void
59  {
60  $this->readClientSalt();
61  }
+ Here is the call graph for this function:

◆ isBackwardCompatibilityEnabled()

ilBcryptPasswordEncoder::isBackwardCompatibilityEnabled ( )

Definition at line 78 of file class.ilBcryptPasswordEncoder.php.

References $backward_compatibility.

Referenced by encode().

78  : bool
79  {
81  }
+ Here is the caller graph for this function:

◆ isBcryptSupported()

ilBcryptPasswordEncoder::isBcryptSupported ( )
protected

Definition at line 63 of file class.ilBcryptPasswordEncoder.php.

Referenced by encode().

63  : bool
64  {
65  return PHP_VERSION_ID >= 50307;
66  }
+ Here is the caller graph for this function:

◆ isPasswordValid()

ilBcryptPasswordEncoder::isPasswordValid ( string  $encoded,
string  $raw,
string  $salt 
)

Checks a raw password against an encoded password.

The raw password has to be injected into the encoder instance before.

Parameters
string$encodedAn encoded password
string$rawA raw password
string$saltThe salt, may be empty
Returns
Boolean true if the password is valid, false otherwise

Implements ilPasswordEncoder.

Definition at line 124 of file class.ilBcryptPasswordEncoder.php.

References check(), getClientSalt(), and ilBasePasswordEncoder\isPasswordTooLong().

Referenced by ilBcryptPasswordEncoderTest\testPasswordShouldBeCorrectlyEncodedAndVerified(), and ilBcryptPasswordEncoderTest\testPasswordVerificationShouldFailIfTheRawPasswordExceedsTheSupportedLength().

124  : bool
125  {
126  if (!$this->getClientSalt()) {
127  throw new ilPasswordException('Missing client salt.');
128  }
129 
130  return !$this->isPasswordTooLong($raw) && $this->check($encoded, $raw, $salt);
131  }
check(string $encoded, string $raw, string $salt)
Class for user password exception handling in ILIAS.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ isSecurityFlawIgnored()

ilBcryptPasswordEncoder::isSecurityFlawIgnored ( )

Definition at line 91 of file class.ilBcryptPasswordEncoder.php.

References $is_security_flaw_ignored.

Referenced by encode().

91  : bool
92  {
94  }
+ Here is the caller graph for this function:

◆ readClientSalt()

ilBcryptPasswordEncoder::readClientSalt ( )
private

Definition at line 206 of file class.ilBcryptPasswordEncoder.php.

References generateClientSalt(), getClientSaltLocation(), setClientSalt(), and storeClientSalt().

Referenced by init().

206  : void
207  {
208  if (is_file($this->getClientSaltLocation()) && is_readable($this->getClientSaltLocation())) {
209  $contents = file_get_contents($this->getClientSaltLocation());
210  if ($contents !== false && trim($contents) !== '') {
211  $this->setClientSalt($contents);
212  }
213  } else {
214  $this->generateClientSalt();
215  $this->storeClientSalt();
216  }
217  }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ requiresReencoding()

ilBcryptPasswordEncoder::requiresReencoding ( string  $encoded)

Returns whether the encoded password needs to be re-encoded.

Implements ilPasswordEncoder.

Definition at line 143 of file class.ilBcryptPasswordEncoder.php.

Referenced by ilBcryptPasswordEncoderTest\testEncoderDoesNotSupportReencoding().

143  : bool
144  {
145  return false;
146  }
+ Here is the caller graph for this function:

◆ requiresSalt()

ilBcryptPasswordEncoder::requiresSalt ( )

Returns whether the encoder requires a salt.

Implements ilPasswordEncoder.

Definition at line 138 of file class.ilBcryptPasswordEncoder.php.

Referenced by ilBcryptPasswordEncoderTest\testEncoderReliesOnSalts().

138  : bool
139  {
140  return true;
141  }
+ Here is the caller graph for this function:

◆ setBackwardCompatibility()

ilBcryptPasswordEncoder::setBackwardCompatibility ( bool  $backward_compatibility)

Set the backward compatibility $2a$ instead of $2y$ for PHP 5.3.7+.

Definition at line 86 of file class.ilBcryptPasswordEncoder.php.

References $backward_compatibility.

86  : void
87  {
88  $this->backward_compatibility = $backward_compatibility;
89  }

◆ setClientSalt()

ilBcryptPasswordEncoder::setClientSalt ( ?string  $client_salt)

Definition at line 106 of file class.ilBcryptPasswordEncoder.php.

References $client_salt.

Referenced by generateClientSalt(), and readClientSalt().

106  : void
107  {
108  $this->client_salt = $client_salt;
109  }
+ Here is the caller graph for this function:

◆ setDataDirectory()

ilBcryptPasswordEncoder::setDataDirectory ( string  $data_directory)

Definition at line 73 of file class.ilBcryptPasswordEncoder.php.

References $data_directory.

Referenced by __construct().

73  : void
74  {
75  $this->data_directory = $data_directory;
76  }
+ Here is the caller graph for this function:

◆ setIsSecurityFlawIgnored()

ilBcryptPasswordEncoder::setIsSecurityFlawIgnored ( bool  $is_security_flaw_ignored)

Definition at line 96 of file class.ilBcryptPasswordEncoder.php.

References $is_security_flaw_ignored.

Referenced by __construct().

96  : void
97  {
98  $this->is_security_flaw_ignored = $is_security_flaw_ignored;
99  }
+ Here is the caller graph for this function:

◆ storeClientSalt()

ilBcryptPasswordEncoder::storeClientSalt ( )
private

Definition at line 226 of file class.ilBcryptPasswordEncoder.php.

References Vendor\Package\$e, $location, $message, getClientSalt(), and getClientSaltLocation().

Referenced by readClientSalt().

226  : void
227  {
228  $location = $this->getClientSaltLocation();
229 
230  set_error_handler(static function (int $severity, string $message, string $file, int $line): void {
231  throw new ErrorException($message, $severity, $severity, $file, $line);
232  });
233 
234  try {
235  $result = file_put_contents($location, $this->getClientSalt());
236  if (!$result) {
237  throw new ilPasswordException(sprintf(
238  'Could not store the client salt in: %s. Please contact an administrator.',
239  $location
240  ));
241  }
242  } catch (Exception $e) {
243  throw new ilPasswordException(sprintf(
244  'Could not store the client salt in: %s. Please contact an administrator.',
245  $location
246  ));
247  } finally {
248  restore_error_handler();
249  }
250  }
$location
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Definition: buildRTE.php:22
Class for user password exception handling in ILIAS.
$message
Definition: xapiexit.php:32
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Field Documentation

◆ $backward_compatibility

bool ilBcryptPasswordEncoder::$backward_compatibility = false
private

◆ $client_salt

string ilBcryptPasswordEncoder::$client_salt = null
private

Definition at line 35 of file class.ilBcryptPasswordEncoder.php.

Referenced by getClientSalt(), and setClientSalt().

◆ $data_directory

string ilBcryptPasswordEncoder::$data_directory = ''
private

Definition at line 38 of file class.ilBcryptPasswordEncoder.php.

Referenced by getDataDirectory(), and setDataDirectory().

◆ $is_security_flaw_ignored

bool ilBcryptPasswordEncoder::$is_security_flaw_ignored = false
private

◆ MIN_SALT_SIZE

const ilBcryptPasswordEncoder::MIN_SALT_SIZE = 16
private

Definition at line 30 of file class.ilBcryptPasswordEncoder.php.

◆ SALT_STORAGE_FILENAME

const ilBcryptPasswordEncoder::SALT_STORAGE_FILENAME = 'pwsalt.txt'

The documentation for this class was generated from the following file: