Path: blob/master/src/infrastructure/util/password/PhabricatorBcryptPasswordHasher.php
12241 views
<?php12final class PhabricatorBcryptPasswordHasher3extends PhabricatorPasswordHasher {45public function getHumanReadableName() {6return pht('bcrypt');7}89public function getHashName() {10return 'bcrypt';11}1213public function getHashLength() {14return 60;15}1617public function canHashPasswords() {18return function_exists('password_hash');19}2021public function getInstallInstructions() {22return pht('Upgrade to PHP 5.5.0 or newer.');23}2425public function getStrength() {26return 2.0;27}2829public function getHumanReadableStrength() {30return pht('Good');31}3233protected function getPasswordHash(PhutilOpaqueEnvelope $envelope) {34$raw_input = $envelope->openEnvelope();3536$options = array(37'cost' => $this->getBcryptCost(),38);3940$raw_hash = password_hash($raw_input, PASSWORD_BCRYPT, $options);4142return new PhutilOpaqueEnvelope($raw_hash);43}4445protected function verifyPassword(46PhutilOpaqueEnvelope $password,47PhutilOpaqueEnvelope $hash) {48return password_verify($password->openEnvelope(), $hash->openEnvelope());49}5051protected function canUpgradeInternalHash(PhutilOpaqueEnvelope $hash) {52$info = password_get_info($hash->openEnvelope());5354// NOTE: If the costs don't match -- even if the new cost is lower than55// the old cost -- count this as an upgrade. This allows costs to be56// adjusted down and hashing to be migrated toward the new cost if costs57// are ever configured too high for some reason.5859$cost = idx($info['options'], 'cost');60if ($cost != $this->getBcryptCost()) {61return true;62}6364return false;65}6667private function getBcryptCost() {68// NOTE: The default cost is "10", but my laptop can do a hash of cost69// "12" in about 300ms. Since server hardware is often virtualized or old,70// just split the difference.71return 11;72}7374}757677