diff options
author | Morris Jobke <hey@morrisjobke.de> | 2018-04-11 11:04:42 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-04-11 11:04:42 +0200 |
commit | 185a260f6b66e65c96be090a4e7e2453d3888d34 (patch) | |
tree | 31b7eae5de616e968b3e0f1ad7285a9eeece0d62 /lib | |
parent | ecc3bc64aab8c8e490492145a1c819c0e643638e (diff) | |
parent | 84316aec6665eb553e4bda5336913f27cf32f232 (diff) | |
download | nextcloud-server-185a260f6b66e65c96be090a4e7e2453d3888d34.tar.gz nextcloud-server-185a260f6b66e65c96be090a4e7e2453d3888d34.zip |
Merge pull request #9074 from nextcloud/ARGON2I
Add ARGON2I support to the hasher
Diffstat (limited to 'lib')
-rw-r--r-- | lib/private/Security/Hasher.php | 45 |
1 files changed, 36 insertions, 9 deletions
diff --git a/lib/private/Security/Hasher.php b/lib/private/Security/Hasher.php index c6c9109b336..e20de729f4f 100644 --- a/lib/private/Security/Hasher.php +++ b/lib/private/Security/Hasher.php @@ -51,11 +51,9 @@ class Hasher implements IHasher { /** @var IConfig */ private $config; /** @var array Options passed to password_hash and password_needs_rehash */ - private $options = array(); + private $options = []; /** @var string Salt used for legacy passwords */ private $legacySalt = null; - /** @var int Current version of the generated hash */ - private $currentVersion = 1; /** * @param IConfig $config @@ -78,7 +76,11 @@ class Hasher implements IHasher { * @return string Hash of the message with appended version parameter */ public function hash(string $message): string { - return $this->currentVersion . '|' . password_hash($message, PASSWORD_DEFAULT, $this->options); + if (\defined('PASSWORD_ARGON2I')) { + return 2 . '|' . password_hash($message, PASSWORD_ARGON2I, $this->options); + } else { + return 1 . '|' . password_hash($message, PASSWORD_BCRYPT, $this->options); + } } /** @@ -90,7 +92,7 @@ class Hasher implements IHasher { $explodedString = explode('|', $prefixedHash, 2); if(\count($explodedString) === 2) { if((int)$explodedString[0] > 0) { - return array('version' => (int)$explodedString[0], 'hash' => $explodedString[1]); + return ['version' => (int)$explodedString[0], 'hash' => $explodedString[1]]; } } @@ -111,8 +113,8 @@ class Hasher implements IHasher { // Verify whether it matches a legacy PHPass or SHA1 string $hashLength = \strlen($hash); - if($hashLength === 60 && password_verify($message.$this->legacySalt, $hash) || - $hashLength === 40 && hash_equals($hash, sha1($message))) { + if(($hashLength === 60 && password_verify($message.$this->legacySalt, $hash)) || + ($hashLength === 40 && hash_equals($hash, sha1($message)))) { $newHash = $this->hash($message); return true; } @@ -121,7 +123,7 @@ class Hasher implements IHasher { } /** - * Verify V1 hashes + * Verify V1 (blowfish) hashes * @param string $message Message to verify * @param string $hash Assumed hash of the message * @param null|string &$newHash Reference will contain the updated hash if necessary. Update the existing hash with this one. @@ -129,7 +131,30 @@ class Hasher implements IHasher { */ protected function verifyHashV1(string $message, string $hash, &$newHash = null): bool { if(password_verify($message, $hash)) { - if(password_needs_rehash($hash, PASSWORD_DEFAULT, $this->options)) { + $algo = PASSWORD_BCRYPT; + if (\defined('PASSWORD_ARGON2I')) { + $algo = PASSWORD_ARGON2I; + } + + if(password_needs_rehash($hash, $algo, $this->options)) { + $newHash = $this->hash($message); + } + return true; + } + + return false; + } + + /** + * Verify V2 (argon2i) hashes + * @param string $message Message to verify + * @param string $hash Assumed hash of the message + * @param null|string &$newHash Reference will contain the updated hash if necessary. Update the existing hash with this one. + * @return bool Whether $hash is a valid hash of $message + */ + protected function verifyHashV2(string $message, string $hash, &$newHash = null) : bool { + if(password_verify($message, $hash)) { + if(password_needs_rehash($hash, PASSWORD_ARGON2I, $this->options)) { $newHash = $this->hash($message); } return true; @@ -149,6 +174,8 @@ class Hasher implements IHasher { if(isset($splittedHash['version'])) { switch ($splittedHash['version']) { + case 2: + return $this->verifyHashV2($message, $splittedHash['hash'], $newHash); case 1: return $this->verifyHashV1($message, $splittedHash['hash'], $newHash); } |