aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Alexander <admin@m-a-styles.de>2016-08-09 21:07:49 +0200
committerMarc Alexander <admin@m-a-styles.de>2016-10-03 22:09:07 +0200
commit1d40c0f43b366638de16a99a874ce1475249ade0 (patch)
tree4342364241a0eba7660784b8a89c2b64380b1a4c
parent7bb4e88acdb0f45f8bfbad74b558db65524cbe1a (diff)
downloadforums-1d40c0f43b366638de16a99a874ce1475249ade0.tar
forums-1d40c0f43b366638de16a99a874ce1475249ade0.tar.gz
forums-1d40c0f43b366638de16a99a874ce1475249ade0.tar.bz2
forums-1d40c0f43b366638de16a99a874ce1475249ade0.tar.xz
forums-1d40c0f43b366638de16a99a874ce1475249ade0.zip
[ticket/14733] Support increasing hashing cost factor
PHPBB3-14733
-rw-r--r--phpBB/config/default/container/services_password.yml5
-rw-r--r--phpBB/phpbb/passwords/driver/base.php8
-rw-r--r--phpBB/phpbb/passwords/driver/bcrypt.php31
-rw-r--r--phpBB/phpbb/passwords/driver/driver_interface.php8
-rw-r--r--phpBB/phpbb/passwords/manager.php2
-rw-r--r--tests/passwords/drivers_test.php23
-rw-r--r--tests/passwords/manager_test.php4
7 files changed, 75 insertions, 6 deletions
diff --git a/phpBB/config/default/container/services_password.yml b/phpBB/config/default/container/services_password.yml
index 82850dc2a7..c276365c56 100644
--- a/phpBB/config/default/container/services_password.yml
+++ b/phpBB/config/default/container/services_password.yml
@@ -1,3 +1,6 @@
+parameters:
+ passwords.driver.bcrypt_cost: 10
+
services:
# ----- Password management -----
passwords.manager:
@@ -29,6 +32,7 @@ services:
arguments:
- '@config'
- '@passwords.driver_helper'
+ - '%passwords.driver.bcrypt_cost%'
tags:
- { name: passwords.driver }
@@ -37,6 +41,7 @@ services:
arguments:
- '@config'
- '@passwords.driver_helper'
+ - '%passwords.driver.bcrypt_cost%'
tags:
- { name: passwords.driver }
diff --git a/phpBB/phpbb/passwords/driver/base.php b/phpBB/phpbb/passwords/driver/base.php
index fd07a61bf4..49b96af372 100644
--- a/phpBB/phpbb/passwords/driver/base.php
+++ b/phpBB/phpbb/passwords/driver/base.php
@@ -53,6 +53,14 @@ abstract class base implements driver_interface
}
/**
+ * {@inheritdoc}
+ */
+ public function needs_rehash($hash)
+ {
+ return false;
+ }
+
+ /**
* {@inheritdoc}
*/
public function get_settings_only($hash, $full = false)
diff --git a/phpBB/phpbb/passwords/driver/bcrypt.php b/phpBB/phpbb/passwords/driver/bcrypt.php
index eab1c3d569..39fb5e5cf1 100644
--- a/phpBB/phpbb/passwords/driver/bcrypt.php
+++ b/phpBB/phpbb/passwords/driver/bcrypt.php
@@ -17,6 +17,23 @@ class bcrypt extends base
{
const PREFIX = '$2a$';
+ /** @var int Hashing cost factor */
+ protected $cost_factor;
+
+ /**
+ * Constructor of passwords driver object
+ *
+ * @param \phpbb\config\config $config phpBB config
+ * @param \phpbb\passwords\driver\helper $helper Password driver helper
+ */
+ public function __construct(\phpbb\config\config $config, helper $helper, $cost_factor)
+ {
+ parent::__construct($config, $helper);
+
+ // Don't allow cost factor to be below default setting
+ $this->cost_factor = max(10, $cost_factor);
+ }
+
/**
* {@inheritdoc}
*/
@@ -26,6 +43,18 @@ class bcrypt extends base
}
/**
+ * {@inheritdoc}
+ */
+ public function needs_rehash($hash)
+ {
+ preg_match('/^' . preg_quote($this->get_prefix()) . '([0-9]+)\$/', $hash, $matches);
+
+ list(, $cost_factor) = $matches;
+
+ return empty($cost_factor) || $this->cost_factor !== intval($cost_factor);
+ }
+
+ /**
* {@inheritdoc}
*/
public function hash($password, $salt = '')
@@ -46,7 +75,7 @@ class bcrypt extends base
if ($salt == '')
{
- $salt = $prefix . '10$' . $this->get_random_salt();
+ $salt = $prefix . $this->cost_factor . '$' . $this->get_random_salt();
}
$hash = crypt($password, $salt);
diff --git a/phpBB/phpbb/passwords/driver/driver_interface.php b/phpBB/phpbb/passwords/driver/driver_interface.php
index 3974484f13..6a660b80ea 100644
--- a/phpBB/phpbb/passwords/driver/driver_interface.php
+++ b/phpBB/phpbb/passwords/driver/driver_interface.php
@@ -30,6 +30,14 @@ interface driver_interface
public function is_legacy();
/**
+ * Check if password needs to be rehashed
+ *
+ * @param string $hash Hash to check for rehash
+ * @return bool True if password needs to be rehashed, false if not
+ */
+ public function needs_rehash($hash);
+
+ /**
* Returns the hash prefix
*
* @return string Hash prefix
diff --git a/phpBB/phpbb/passwords/manager.php b/phpBB/phpbb/passwords/manager.php
index b2caba81f2..38c12995b4 100644
--- a/phpBB/phpbb/passwords/manager.php
+++ b/phpBB/phpbb/passwords/manager.php
@@ -297,7 +297,7 @@ class manager
}
else
{
- $this->convert_flag = false;
+ $this->convert_flag = $stored_hash_type->needs_rehash($hash);
}
// Check all legacy hash types if prefix is $CP$
diff --git a/tests/passwords/drivers_test.php b/tests/passwords/drivers_test.php
index 5f9fd523c9..01c69a38bb 100644
--- a/tests/passwords/drivers_test.php
+++ b/tests/passwords/drivers_test.php
@@ -23,8 +23,8 @@ class phpbb_passwords_helper_test extends \phpbb_test_case
$php_ext = 'php';
$this->passwords_drivers = array(
- 'passwords.driver.bcrypt_2y' => new \phpbb\passwords\driver\bcrypt_2y($config, $this->driver_helper),
- 'passwords.driver.bcrypt' => new \phpbb\passwords\driver\bcrypt($config, $this->driver_helper),
+ 'passwords.driver.bcrypt_2y' => new \phpbb\passwords\driver\bcrypt_2y($config, $this->driver_helper, 10),
+ 'passwords.driver.bcrypt' => new \phpbb\passwords\driver\bcrypt($config, $this->driver_helper, 10),
'passwords.driver.salted_md5' => new \phpbb\passwords\driver\salted_md5($config, $this->driver_helper),
'passwords.driver.phpass' => new \phpbb\passwords\driver\phpass($config, $this->driver_helper),
'passwords.driver.sha1_smf' => new \phpbb\passwords\driver\sha1_smf($config, $this->driver_helper),
@@ -413,4 +413,23 @@ class phpbb_passwords_helper_test extends \phpbb_test_case
);
return strtr($string, $transform);
}
+
+ public function data_needs_rehash()
+ {
+ return array(
+ array('passwords.driver.bcrypt_2y', '$2y$10$somerandomhash', false),
+ array('passwords.driver.bcrypt', '$2a$10$somerandomhash', false),
+ array('passwords.driver.salted_md5', 'foobar', false),
+ array('passwords.driver.bcrypt_2y', '$2y$9$somerandomhash', true),
+ array('passwords.driver.bcrypt', '$2a$04$somerandomhash', true),
+ );
+ }
+
+ /**
+ * @dataProvider data_needs_rehash
+ */
+ public function test_needs_rehash($driver, $hash, $expected)
+ {
+ $this->assertSame($this->passwords_drivers[$driver]->needs_rehash($hash), $expected);
+ }
}
diff --git a/tests/passwords/manager_test.php b/tests/passwords/manager_test.php
index 333834ee07..dbe0341664 100644
--- a/tests/passwords/manager_test.php
+++ b/tests/passwords/manager_test.php
@@ -29,8 +29,8 @@ class phpbb_passwords_manager_test extends \phpbb_test_case
$php_ext = 'php';
$this->passwords_drivers = array(
- 'passwords.driver.bcrypt_2y' => new \phpbb\passwords\driver\bcrypt_2y($config, $this->driver_helper),
- 'passwords.driver.bcrypt' => new \phpbb\passwords\driver\bcrypt($config, $this->driver_helper),
+ 'passwords.driver.bcrypt_2y' => new \phpbb\passwords\driver\bcrypt_2y($config, $this->driver_helper, 10),
+ 'passwords.driver.bcrypt' => new \phpbb\passwords\driver\bcrypt($config, $this->driver_helper, 10),
'passwords.driver.salted_md5' => new \phpbb\passwords\driver\salted_md5($config, $this->driver_helper),
'passwords.driver.phpass' => new \phpbb\passwords\driver\phpass($config, $this->driver_helper),
'passwords.driver.convert_password' => new \phpbb\passwords\driver\convert_password($config, $this->driver_helper),