MediaWiki
REL1_24
|
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 }