MediaWiki  REL1_24
BcryptPassword.php
Go to the documentation of this file.
00001 <?php
00031 class BcryptPassword extends ParameterizedPassword {
00032     protected function getDefaultParams() {
00033         return array(
00034             'rounds' => $this->config['cost'],
00035         );
00036     }
00037 
00038     protected function getDelimiter() {
00039         return '$';
00040     }
00041 
00042     protected function parseHash( $hash ) {
00043         parent::parseHash( $hash );
00044 
00045         $this->params['rounds'] = (int)$this->params['rounds'];
00046     }
00047 
00054     public function crypt( $password ) {
00055         if ( !defined( 'CRYPT_BLOWFISH' ) ) {
00056             throw new MWException( 'Bcrypt is not supported.' );
00057         }
00058 
00059         // Either use existing hash or make a new salt
00060         // Bcrypt expects 22 characters of base64-encoded salt
00061         // Note: bcrypt does not use MIME base64. It uses its own base64 without any '=' padding.
00062         //       It expects a 128 bit salt, so it will ignore anything after the first 128 bits
00063         if ( !isset( $this->args[0] ) ) {
00064             $this->args[] = substr(
00065                 // Replace + with ., because bcrypt uses a non-MIME base64 format
00066                 strtr(
00067                     // Random base64 encoded string
00068                     base64_encode( MWCryptRand::generate( 16, true ) ),
00069                     '+', '.'
00070                 ),
00071                 0, 22
00072             );
00073         }
00074 
00075         $hash = crypt( $password,
00076             sprintf( '$2y$%02d$%s', (int)$this->params['rounds'], $this->args[0] ) );
00077 
00078         if ( !is_string( $hash ) || strlen( $hash ) <= 13 ) {
00079             throw new PasswordError( 'Error when hashing password.' );
00080         }
00081 
00082         // Strip the $2y$
00083         $parts = explode( $this->getDelimiter(), substr( $hash, 4 ) );
00084         $this->params['rounds'] = (int)$parts[0];
00085         $this->args[0] = substr( $parts[1], 0, 22 );
00086         $this->hash = substr( $parts[1], 22 );
00087     }
00088 }