From 2a6f347430f93a57e3ed194e9509745c690f522b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20Chilliet?= Date: Thu, 11 May 2023 17:20:44 +0200 Subject: [PATCH 1/2] Increase from 100000 to 600000 iterations for hash_pbkdf2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Côme Chilliet --- apps/encryption/lib/Crypto/Crypt.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/apps/encryption/lib/Crypto/Crypt.php b/apps/encryption/lib/Crypto/Crypt.php index 0cf6451d287bd..cd2453e8c70c7 100644 --- a/apps/encryption/lib/Crypto/Crypt.php +++ b/apps/encryption/lib/Crypto/Crypt.php @@ -70,9 +70,9 @@ class Crypt { // default cipher from old Nextcloud versions public const LEGACY_CIPHER = 'AES-128-CFB'; - public const SUPPORTED_KEY_FORMATS = ['hash', 'password']; + public const SUPPORTED_KEY_FORMATS = ['hash2', 'hash', 'password']; // one out of SUPPORTED_KEY_FORMATS - public const DEFAULT_KEY_FORMAT = 'hash'; + public const DEFAULT_KEY_FORMAT = 'hash2'; // default key format, old Nextcloud version encrypted the private key directly // with the user password public const LEGACY_KEY_FORMAT = 'password'; @@ -371,22 +371,20 @@ private function addPadding($data) { * @param string $uid only used for user keys * @return string */ - protected function generatePasswordHash($password, $cipher, $uid = '') { + protected function generatePasswordHash(string $password, string $cipher, string $uid = '', int $iterations = 600000): string { $instanceId = $this->config->getSystemValue('instanceid'); $instanceSecret = $this->config->getSystemValue('secret'); $salt = hash('sha256', $uid . $instanceId . $instanceSecret, true); $keySize = $this->getKeySize($cipher); - $hash = hash_pbkdf2( + return hash_pbkdf2( 'sha256', $password, $salt, - 100000, + $iterations, $keySize, true ); - - return $hash; } /** @@ -431,8 +429,10 @@ public function decryptPrivateKey($privateKey, $password = '', $uid = '') { $keyFormat = self::LEGACY_KEY_FORMAT; } - if ($keyFormat === self::DEFAULT_KEY_FORMAT) { - $password = $this->generatePasswordHash($password, $cipher, $uid); + if ($keyFormat === 'hash') { + $password = $this->generatePasswordHash($password, $cipher, $uid, 100000); + } elseif ($keyFormat === 'hash2') { + $password = $this->generatePasswordHash($password, $cipher, $uid, 600000); } $binaryEncoding = isset($header['encoding']) && $header['encoding'] === self::BINARY_ENCODING_FORMAT; From 99bdb15398e33bc2212dc238dfe5c1f845d565c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20Chilliet?= Date: Thu, 25 May 2023 16:31:27 +0200 Subject: [PATCH 2/2] Adapt encryption test to change in generateHeader MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Côme Chilliet --- apps/encryption/tests/Crypto/CryptTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/encryption/tests/Crypto/CryptTest.php b/apps/encryption/tests/Crypto/CryptTest.php index dd41c67e8ad99..0bb2c652d8b3b 100644 --- a/apps/encryption/tests/Crypto/CryptTest.php +++ b/apps/encryption/tests/Crypto/CryptTest.php @@ -137,7 +137,7 @@ public function testGenerateHeaderInvalid() { */ public function dataTestGenerateHeader() { return [ - [null, 'HBEGIN:cipher:AES-128-CFB:keyFormat:hash:encoding:binary:HEND'], + [null, 'HBEGIN:cipher:AES-128-CFB:keyFormat:hash2:encoding:binary:HEND'], ['password', 'HBEGIN:cipher:AES-128-CFB:keyFormat:password:encoding:binary:HEND'], ['hash', 'HBEGIN:cipher:AES-128-CFB:keyFormat:hash:encoding:binary:HEND'] ];