summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorMorris Jobke <hey@morrisjobke.de>2018-04-11 11:04:42 +0200
committerGitHub <noreply@github.com>2018-04-11 11:04:42 +0200
commit185a260f6b66e65c96be090a4e7e2453d3888d34 (patch)
tree31b7eae5de616e968b3e0f1ad7285a9eeece0d62 /lib
parentecc3bc64aab8c8e490492145a1c819c0e643638e (diff)
parent84316aec6665eb553e4bda5336913f27cf32f232 (diff)
downloadnextcloud-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.php45
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);
}