diff options
-rw-r--r-- | _test/cases/inc/auth_password.test.php | 5 | ||||
-rw-r--r-- | inc/PassHash.class.php | 34 | ||||
-rw-r--r-- | lib/plugins/config/settings/config.metadata.php | 2 |
3 files changed, 40 insertions, 1 deletions
diff --git a/_test/cases/inc/auth_password.test.php b/_test/cases/inc/auth_password.test.php index 928552a14..6fe564e73 100644 --- a/_test/cases/inc/auth_password.test.php +++ b/_test/cases/inc/auth_password.test.php @@ -48,6 +48,11 @@ class auth_password_test extends UnitTestCase { } } + function test_bcrypt_self(){ + $hash = auth_cryptPassword('foobcrypt','bcrypt'); + $this->assertTrue(auth_verifyPassword('foobcrypt',$hash)); + } + function test_verifyPassword_nohash(){ $this->assertTrue(auth_verifyPassword('foo','$1$$n1rTiFE0nRifwV/43bVon/')); } diff --git a/inc/PassHash.class.php b/inc/PassHash.class.php index 31493c022..77f2115bd 100644 --- a/inc/PassHash.class.php +++ b/inc/PassHash.class.php @@ -47,6 +47,9 @@ class PassHash { }elseif(preg_match('/^md5\$(.{5})\$/',$hash,$m)){ $method = 'djangomd5'; $salt = $m[1]; + }elseif(preg_match('/^\$2a\$(.{2})\$/',$hash,$m)){ + $method = 'bcrypt'; + $salt = $hash; }elseif(substr($hash,0,6) == '{SSHA}'){ $method = 'ssha'; $salt = substr(base64_decode(substr($hash, 6)),20); @@ -379,4 +382,35 @@ class PassHash { return 'md5$'.$salt.'$'.md5($salt.$clear); } + + /** + * Passwordhashing method 'bcrypt' + * + * Uses a modified blowfish algorithm called eksblowfish + * This method works on PHP 5.3+ only and will throw an exception + * if the needed crypt support isn't available + * + * A full hash should be given as salt (starting with $a2$) or this + * will break. When no salt is given, the iteration count can be set + * through the $compute variable. + * + * @param string $clear - the clear text to hash + * @param string $salt - the salt to use, null for random + * @param int $compute - the iteration count (between 4 and 31) + * @returns string - hashed password + */ + public function hash_bcrypt($clear, $salt=null, $compute=8){ + if(!defined('CRYPT_BLOWFISH') || CRYPT_BLOWFISH != 1){ + throw new Exception('This PHP installation has no bcrypt support'); + } + + if(is_null($salt)){ + if($compute < 4 || $compute > 31) $compute = 8; + $salt = '$2a$'.str_pad($compute, 2, '0', STR_PAD_LEFT).'$'. + $this->gen_salt(22); + } + + return crypt($password, $salt); + } + } diff --git a/lib/plugins/config/settings/config.metadata.php b/lib/plugins/config/settings/config.metadata.php index 5f2c32ea7..ba14eb85a 100644 --- a/lib/plugins/config/settings/config.metadata.php +++ b/lib/plugins/config/settings/config.metadata.php @@ -123,7 +123,7 @@ $meta['_authentication'] = array('fieldset'); $meta['useacl'] = array('onoff'); $meta['autopasswd'] = array('onoff'); $meta['authtype'] = array('authtype'); -$meta['passcrypt'] = array('multichoice','_choices' => array('smd5','md5','apr1','sha1','ssha','crypt','mysql','my411','kmd5','pmd5','hmd5')); +$meta['passcrypt'] = array('multichoice','_choices' => array('smd5','md5','apr1','sha1','ssha','crypt','mysql','my411','kmd5','pmd5','hmd5','bcrypt')); $meta['defaultgroup']= array('string'); $meta['superuser'] = array('string'); $meta['manager'] = array('string'); |