ILIAS  release_5-1 Revision 5.0.0-5477-g43f3e3fab5
ilBcryptPasswordEncoder Class Reference
+ Inheritance diagram for ilBcryptPasswordEncoder:
+ Collaboration diagram for ilBcryptPasswordEncoder:

Public Member Functions

 __construct (array $config=array())
 
 isBackwardCompatibilityEnabled ()
 
 setBackwardCompatibility ($backward_compatibility)
 Set the backward compatibility $2a$ instead of $2y$ for PHP 5.3.7+. More...
 
 isSecurityFlawIgnored ()
 
 setIsSecurityFlawIgnored ($is_security_flaw_ignored)
 
 getClientSalt ()
 
 setClientSalt ($client_salt)
 
 getCosts ()
 
 setCosts ($costs)
 
 encodePassword ($raw, $salt)
 {Encodes the raw password.
Parameters
string$rawThe password to encode
string$saltThe salt
Returns
string The encoded password
} More...
 
 isPasswordValid ($encoded, $raw, $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
Returns
Boolean true if the password is valid, false otherwise
} More...
 
 getName ()
 {Returns a unique name/id of the concrete password encoder.
Returns
string
} More...
 
 requiresSalt ()
 {Returns whether or not the encoder requires a salt.
Returns
boolean
} More...
 
 getClientSaltLocation ()
 

Data Fields

const MIN_SALT_SIZE = 16
 
const SALT_STORAGE_FILENAME = 'pwsalt.txt'
 
- Data Fields inherited from ilBasePasswordEncoder
const MAX_PASSWORD_LENGTH = 4096
 

Protected Member Functions

 init ()
 
 isBcryptSupported ()
 
 encode ($raw, $user_secret)
 Generates a bcrypt encoded string. More...
 
 check ($encoded, $raw, $salt)
 Verifies a bcrypt encoded string. More...
 
- Protected Member Functions inherited from ilBasePasswordEncoder
 comparePasswords ($known_string, $user_string)
 Compares two passwords. More...
 
 isPasswordTooLong ($password)
 Checks if the password is too long. More...
 

Protected Attributes

 $client_salt = null
 
 $costs = '08'
 
 $is_security_flaw_ignored = false
 
 $backward_compatibility = false
 

Private Member Functions

 readClientSalt ()
 
 generateClientSalt ()
 
 storeClientSalt ()
 

Detailed Description

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

Constructor & Destructor Documentation

◆ __construct()

ilBcryptPasswordEncoder::__construct ( array  $config = array())
Parameters
array$config
Exceptions
ilPasswordException

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

References init(), setCosts(), and setIsSecurityFlawIgnored().

48  {
49  if(!empty($config))
50  {
51  foreach($config as $key => $value)
52  {
53  switch(strtolower($key))
54  {
55  case 'cost':
56  $this->setCosts($value);
57  break;
58 
59  case 'ignore_security_flaw':
60  $this->setIsSecurityFlawIgnored($value);
61  break;
62  }
63  }
64  }
65 
66  $this->init();
67  }
setIsSecurityFlawIgnored($is_security_flaw_ignored)
+ Here is the call graph for this function:

Member Function Documentation

◆ check()

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

Verifies a bcrypt encoded string.

Parameters
string$encoded
string$raw
string$salt
Returns
bool

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

References getClientSalt().

Referenced by isPasswordValid().

265  {
266  $hashed_password = hash_hmac('whirlpool', str_pad($raw, strlen($raw) * 4, sha1($salt), STR_PAD_BOTH), $this->getClientSalt(), true);
267  return crypt($hashed_password, substr($encoded, 0, 30)) == $encoded;
268  }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ encode()

ilBcryptPasswordEncoder::encode (   $raw,
  $user_secret 
)
protected

Generates a bcrypt encoded string.

Parameters
string$rawThe raw password
string$user_secretA randomly generated string (should be 16 ASCII chars)
Returns
string
Exceptions
ilPasswordException

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

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

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

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

Referenced by encodePassword().

219  {
220  $client_secret = $this->getClientSalt();
221  $hashed_password = hash_hmac('whirlpool', str_pad($raw, strlen($raw) * 4, sha1($user_secret), STR_PAD_BOTH), $client_secret, true);
222  $salt = substr(str_shuffle(str_repeat('./0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', 22)), 0, 22);
223 
228  if($this->isBcryptSupported() && !$this->isBackwardCompatibilityEnabled())
229  {
230  $prefix = '$2y$';
231  }
232  else
233  {
234  $prefix = '$2a$';
235  // check if the password contains 8-bit character
236  if(!$this->isSecurityFlawIgnored() && preg_match('/[\x80-\xFF]/', $raw))
237  {
238  require_once 'Services/Password/exceptions/class.ilPasswordException.php';
239  throw new ilPasswordException(
240  'The bcrypt implementation used by PHP can contain a security flaw ' .
241  'using passwords with 8-bit characters. ' .
242  'We suggest to upgrade to PHP 5.3.7+ or use passwords with only 7-bit characters.'
243  );
244  }
245  }
246 
247  $salted_password = crypt($hashed_password, $prefix . $this->getCosts() . '$' . $salt);
248  if(strlen($salted_password) <= 13)
249  {
250  require_once 'Services/Password/exceptions/class.ilPasswordException.php';
251  throw new ilPasswordException('Error during the bcrypt generation');
252  }
253 
254  return $salted_password;
255  }
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 (   $raw,
  $salt 
)

{Encodes the raw password.

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

Exceptions
ilPasswordException

Implements ilPasswordEncoder.

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

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

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

165  {
166  if(!$this->getClientSalt())
167  {
168  require_once 'Services/Password/exceptions/class.ilPasswordException.php';
169  throw new ilPasswordException('Missing client salt.');
170  }
171 
172  if($this->isPasswordTooLong($raw))
173  {
174  require_once 'Services/Password/exceptions/class.ilPasswordException.php';
175  throw new ilPasswordException('Invalid password.');
176  }
177 
178  return $this->encode($raw, $salt);
179  }
Class for user password exception handling in ILIAS.
encode($raw, $user_secret)
Generates a bcrypt encoded string.
isPasswordTooLong($password)
Checks if the password is too long.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ generateClientSalt()

ilBcryptPasswordEncoder::generateClientSalt ( )
private

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

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

Referenced by readClientSalt().

302  {
303  require_once 'Services/Password/classes/class.ilPasswordUtils.php';
304  $this->setClientSalt(
305  substr(str_replace('+', '.', base64_encode(ilPasswordUtils::getBytes(self::MIN_SALT_SIZE))), 0, 22)
306  );
307  }
static getBytes($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 ( )
Returns
string|null

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

References $client_salt.

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

+ Here is the caller graph for this function:

◆ getClientSaltLocation()

ilBcryptPasswordEncoder::getClientSaltLocation ( )
Returns
string

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

References ilUtil\getDataDir().

Referenced by readClientSalt(), and storeClientSalt().

274  {
275  return ilUtil::getDataDir() . '/' . self::SALT_STORAGE_FILENAME;
276  }
static getDataDir()
get data directory (outside webspace)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getCosts()

ilBcryptPasswordEncoder::getCosts ( )
Returns
string

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

References $costs.

Referenced by encode(), and ilBcryptPasswordEncoderTest\testCostsCanBeRetrievedWhenCostsAreSet().

+ Here is the caller graph for this function:

◆ getName()

ilBcryptPasswordEncoder::getName ( )

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

Returns
string
}

Implements ilPasswordEncoder.

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

199  {
200  return 'bcrypt';
201  }

◆ init()

ilBcryptPasswordEncoder::init ( )
protected

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

References readClientSalt().

Referenced by __construct().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ isBackwardCompatibilityEnabled()

ilBcryptPasswordEncoder::isBackwardCompatibilityEnabled ( )
Returns
boolean

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

References $backward_compatibility.

Referenced by encode().

+ Here is the caller graph for this function:

◆ isBcryptSupported()

ilBcryptPasswordEncoder::isBcryptSupported ( )
protected
Returns
bool

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

Referenced by encode().

81  {
82  return PHP_VERSION_ID >= 50307;
83  }
+ Here is the caller graph for this function:

◆ isPasswordValid()

ilBcryptPasswordEncoder::isPasswordValid (   $encoded,
  $raw,
  $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
Returns
Boolean true if the password is valid, false otherwise
}

Implements ilPasswordEncoder.

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

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

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

185  {
186  if(!$this->getClientSalt())
187  {
188  require_once 'Services/Password/exceptions/class.ilPasswordException.php';
189  throw new ilPasswordException('Missing client salt.');
190  }
191 
192  return !$this->isPasswordTooLong($raw) && $this->check($encoded, $raw, $salt);
193  }
Class for user password exception handling in ILIAS.
check($encoded, $raw, $salt)
Verifies a bcrypt encoded string.
isPasswordTooLong($password)
Checks if the password is too long.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ isSecurityFlawIgnored()

ilBcryptPasswordEncoder::isSecurityFlawIgnored ( )
Returns
boolean

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

References $is_security_flaw_ignored.

Referenced by encode().

+ Here is the caller graph for this function:

◆ readClientSalt()

ilBcryptPasswordEncoder::readClientSalt ( )
private

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

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

Referenced by init().

282  {
283  if(is_file($this->getClientSaltLocation()) && is_readable($this->getClientSaltLocation()))
284  {
285  $contents = file_get_contents($this->getClientSaltLocation());
286  if(strlen(trim($contents)))
287  {
288  $this->setClientSalt($contents);
289  }
290  }
291  else
292  {
293  $this->generateClientSalt();
294  $this->storeClientSalt();
295  }
296  }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ requiresSalt()

ilBcryptPasswordEncoder::requiresSalt ( )

{Returns whether or not the encoder requires a salt.

Returns
boolean
}

Implements ilPasswordEncoder.

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

207  {
208  return true;
209  }

◆ setBackwardCompatibility()

ilBcryptPasswordEncoder::setBackwardCompatibility (   $backward_compatibility)

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

Parameters
boolean$backward_compatibility

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

References $backward_compatibility.

98  {
99  $this->backward_compatibility = (bool)$backward_compatibility;
100  }

◆ setClientSalt()

ilBcryptPasswordEncoder::setClientSalt (   $client_salt)
Parameters
string | null$client_salt

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

References $client_salt.

Referenced by generateClientSalt(), and readClientSalt().

130  {
131  $this->client_salt = $client_salt;
132  }
+ Here is the caller graph for this function:

◆ setCosts()

ilBcryptPasswordEncoder::setCosts (   $costs)
Parameters
string$costs
Exceptions
ilPasswordException

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

References $costs.

Referenced by __construct(), ilBcryptPasswordEncoderTest\testCostsCanBeRetrievedWhenCostsAreSet(), ilBcryptPasswordEncoderTest\testCostsCanBeSetInRange(), ilBcryptPasswordEncoderTest\testCostsCannotBeSetAboveRange(), ilBcryptPasswordEncoderTest\testCostsCannotBeSetBelowRange(), ilBcryptPasswordEncoderTest\testExceptionIsRaisedIfThePasswordExceedsTheSupportedLengthOnEncoding(), ilBcryptPasswordEncoderTest\testPasswordShouldBeCorrectlyEncodedAndVerified(), and ilBcryptPasswordEncoderTest\testPasswordVerificationShouldFailIfTheRawPasswordExceedsTheSupportedLength().

147  {
148  if(!empty($costs))
149  {
150  $costs = (int)$costs;
151  if($costs < 4 || $costs > 31)
152  {
153  require_once 'Services/Password/exceptions/class.ilPasswordException.php';
154  throw new ilPasswordException('The costs parameter of bcrypt must be in range 04-31');
155  }
156  $this->costs = sprintf('%1$02d', $costs);
157  }
158  }
Class for user password exception handling in ILIAS.
+ Here is the caller graph for this function:

◆ setIsSecurityFlawIgnored()

ilBcryptPasswordEncoder::setIsSecurityFlawIgnored (   $is_security_flaw_ignored)
Parameters
boolean$is_security_flaw_ignored

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

References $is_security_flaw_ignored.

Referenced by __construct().

114  {
115  $this->is_security_flaw_ignored = (bool)$is_security_flaw_ignored;
116  }
+ Here is the caller graph for this function:

◆ storeClientSalt()

ilBcryptPasswordEncoder::storeClientSalt ( )
private
Exceptions
ilPasswordException

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

References $result, getClientSalt(), and getClientSaltLocation().

Referenced by readClientSalt().

313  {
314  $result = @file_put_contents($this->getClientSaltLocation(), $this->getClientSalt());
315  if(!$result)
316  {
317  require_once 'Services/Password/exceptions/class.ilPasswordException.php';
318  throw new ilPasswordException(sprintf("Could not store the client salt in: %s. Please contact an administrator.", $this->getClientSaltLocation()));
319  }
320  }
$result
Class for user password exception handling in ILIAS.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Field Documentation

◆ $backward_compatibility

ilBcryptPasswordEncoder::$backward_compatibility = false
protected

◆ $client_salt

ilBcryptPasswordEncoder::$client_salt = null
protected

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

Referenced by getClientSalt(), and setClientSalt().

◆ $costs

ilBcryptPasswordEncoder::$costs = '08'
protected

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

Referenced by getCosts(), and setCosts().

◆ $is_security_flaw_ignored

ilBcryptPasswordEncoder::$is_security_flaw_ignored = false
protected

◆ MIN_SALT_SIZE

const ilBcryptPasswordEncoder::MIN_SALT_SIZE = 16

Definition at line 16 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: