Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F14123358
D8271.id19683.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
3 KB
Referenced Files
None
Subscribers
None
D8271.id19683.diff
View Options
Index: src/infrastructure/util/password/PhabricatorBcryptPasswordHasher.php
===================================================================
--- src/infrastructure/util/password/PhabricatorBcryptPasswordHasher.php
+++ src/infrastructure/util/password/PhabricatorBcryptPasswordHasher.php
@@ -34,12 +34,8 @@
protected function getPasswordHash(PhutilOpaqueEnvelope $envelope) {
$raw_input = $envelope->openEnvelope();
- // NOTE: The default cost is "10", but my laptop can do a hash of cost
- // "12" in about 300ms. Since server hardware is often virtualized or old,
- // just split the difference.
-
$options = array(
- 'cost' => 11,
+ 'cost' => $this->getBcryptCost(),
);
$raw_hash = password_hash($raw_input, CRYPT_BLOWFISH, $options);
@@ -53,4 +49,27 @@
return password_verify($password->openEnvelope(), $hash->openEnvelope());
}
+ protected function canUpgradeInternalHash(PhutilOpaqueEnvelope $hash) {
+ $info = password_get_info($hash->openEnvelope());
+
+ // NOTE: If the costs don't match -- even if the new cost is lower than
+ // the old cost -- count this as an upgrade. This allows costs to be
+ // adjusted down and hashing to be migrated toward the new cost if costs
+ // are ever configured too high for some reason.
+
+ $cost = idx($info['options'], 'cost');
+ if ($cost != $this->getBcryptCost()) {
+ return true;
+ }
+
+ return false;
+ }
+
+ private function getBcryptCost() {
+ // NOTE: The default cost is "10", but my laptop can do a hash of cost
+ // "12" in about 300ms. Since server hardware is often virtualized or old,
+ // just split the difference.
+ return 11;
+ }
+
}
Index: src/infrastructure/util/password/PhabricatorPasswordHasher.php
===================================================================
--- src/infrastructure/util/password/PhabricatorPasswordHasher.php
+++ src/infrastructure/util/password/PhabricatorPasswordHasher.php
@@ -130,6 +130,24 @@
}
+ /**
+ * Check if an existing hash created by this algorithm is upgradeable.
+ *
+ * The default implementation returns `false`. However, hash algorithms which
+ * have (for example) an internal cost function may be able to upgrade an
+ * existing hash to a stronger one with a higher cost.
+ *
+ * @param PhutilOpaqueEnvelope Bare hash.
+ * @return bool True if the hash can be upgraded without
+ * changing the algorithm (for example, to a
+ * higher cost).
+ * @task hasher
+ */
+ protected function canUpgradeInternalHash(PhutilOpaqueEnvelope $hash) {
+ return false;
+ }
+
+
/* -( Using Hashers )------------------------------------------------------ */
@@ -318,7 +336,19 @@
$current_hasher = self::getHasherForHash($hash);
$best_hasher = self::getBestHasher();
- return ($current_hasher->getHashName() != $best_hasher->getHashName());
+ if ($current_hasher->getHashName() != $best_hasher->getHashName()) {
+ // If the algorithm isn't the best one, we can upgrade.
+ return true;
+ }
+
+ $info = self::parseHashFromStorage($hash);
+ if ($current_hasher->canUpgradeInternalHash($info['hash'])) {
+ // If the algorithm provides an internal upgrade, we can also upgrade.
+ return true;
+ }
+
+ // Already on the best algorithm with the best settings.
+ return false;
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Nov 30, 10:02 PM (21 h, 1 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6810617
Default Alt Text
D8271.id19683.diff (3 KB)
Attached To
Mode
D8271: Allow hashers to side-grade hashes across cost settings
Attached
Detach File
Event Timeline
Log In to Comment