aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--_test/tests/inc/auth_password.test.php8
-rw-r--r--inc/PassHash.php42
2 files changed, 39 insertions, 11 deletions
diff --git a/_test/tests/inc/auth_password.test.php b/_test/tests/inc/auth_password.test.php
index beb95c060..c7eaa7002 100644
--- a/_test/tests/inc/auth_password.test.php
+++ b/_test/tests/inc/auth_password.test.php
@@ -124,6 +124,14 @@ class auth_password_test extends DokuWikiTest {
$this->assertTrue($except);
}
+ function test_verifyPassword_sha256_crypt() {
+ if(defined('CRYPT_SHA256') && CRYPT_SHA256 == 1) {
+ $this->assertTrue(auth_verifyPassword('password', '$5$KvtIFskJlsLHR95A$CABu0dPozYsRq/dGNj4KITBQ21ZK.gC9KVXAkYFNE85'));
+ $this->assertTrue(auth_verifyPassword('password', '$5$rounds=1000$FQM/YjSke3Iqsdma$RYwG1MP21u68qUBQKqHoz7GLpWlnA6tunNKMNH3nRh5'));
+ } else {
+ $this->markTestSkipped('SHA256 not available in this PHP environment');
+ }
+ }
/**
* issue #2629, support PHP's crypt() format (with rounds=0 parameter)
*/
diff --git a/inc/PassHash.php b/inc/PassHash.php
index 1189da0b7..19d39af49 100644
--- a/inc/PassHash.php
+++ b/inc/PassHash.php
@@ -92,10 +92,13 @@ class PassHash {
} elseif(preg_match('/^:B:(.+?):.{32}$/', $hash, $m)) {
$method = 'mediawiki';
$salt = $m[1];
- } elseif(preg_match('/^\$6\$(rounds=\d+)?\$?(.+?)\$/', $hash, $m)) {
- $method = 'sha512';
- $salt = $m[2];
- $magic = $m[1];
+ } elseif(preg_match('/^\$(5|6)\$(rounds=\d+)?\$?(.+?)\$/', $hash, $m)) {
+ $method = 'sha2';
+ $salt = $m[3];
+ $magic = array(
+ 'prefix' => $m[1],
+ 'rounds' => $m[2],
+ );
} elseif(preg_match('/^\$(argon2id?)/', $hash, $m)) {
if(!defined('PASSWORD_'.strtoupper($m[1]))) {
throw new \Exception('This PHP installation has no '.strtoupper($m[1]).' support');
@@ -666,26 +669,43 @@ class PassHash {
}
/**
- * Password hashing method SHA512
+ * Password hashing method SHA-2
*
* This is only supported on PHP 5.3.2 or higher and will throw an exception if
* the needed crypt support is not available
*
+ * Uses:
+ * - SHA-2 with 256-bit output for prefix $5$
+ * - SHA-2 with 512-bit output for prefix $6$ (default)
+ *
* @param string $clear The clear text to hash
* @param string $salt The salt to use, null for random
- * @param string $magic The rounds for sha512 (for example "rounds=3000"), null for default value
+ * @param array $opts ('rounds' => rounds for sha256/sha512, 'prefix' => selected method from SHA-2 family)
* @return string Hashed password
* @throws \Exception
*/
- public function hash_sha512($clear, $salt = null, $magic = null) {
- if(!defined('CRYPT_SHA512') || CRYPT_SHA512 != 1) {
+ public function hash_sha2($clear, $salt = null, $opts = array()) {
+ if(empty($opts['prefix'])) {
+ $prefix = '6';
+ } else {
+ $prefix = $opts['prefix'];
+ }
+ if(empty($opts['rounds'])) {
+ $rounds = null;
+ } else {
+ $rounds = $opts['rounds'];
+ }
+ if($prefix == '5' && (!defined('CRYPT_SHA256') || CRYPT_SHA256 != 1)) {
+ throw new \Exception('This PHP installation has no SHA256 support');
+ }
+ if($prefix == '6' && (!defined('CRYPT_SHA512') || CRYPT_SHA512 != 1)) {
throw new \Exception('This PHP installation has no SHA512 support');
}
$this->init_salt($salt, 8, false);
- if(empty($magic)) {
- return crypt($clear, '$6$'.$salt.'$');
+ if(empty($rounds)) {
+ return crypt($clear, '$'.$prefix.'$'.$salt.'$');
}else{
- return crypt($clear, '$6$'.$magic.'$'.$salt.'$');
+ return crypt($clear, '$'.$prefix.'$'.$rounds.'$'.$salt.'$');
}
}