@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.)
hq.recaptime.dev/wiki/Phorge
phorge
phabricator
1<?php
2
3final class PhabricatorBcryptPasswordHasher
4 extends PhabricatorPasswordHasher {
5
6 public function getHumanReadableName() {
7 return pht('bcrypt');
8 }
9
10 public function getHashName() {
11 return 'bcrypt';
12 }
13
14 public function getHashLength() {
15 return 60;
16 }
17
18 public function canHashPasswords() {
19 return function_exists('password_hash');
20 }
21
22 public function getInstallInstructions() {
23 return pht('Upgrade to PHP 5.5.0 or newer.');
24 }
25
26 public function getStrength() {
27 return 2.0;
28 }
29
30 public function getHumanReadableStrength() {
31 return pht('Good');
32 }
33
34 protected function getPasswordHash(PhutilOpaqueEnvelope $envelope) {
35 $raw_input = $envelope->openEnvelope();
36
37 $options = array(
38 'cost' => $this->getBcryptCost(),
39 );
40
41 $raw_hash = password_hash($raw_input, PASSWORD_BCRYPT, $options);
42
43 return new PhutilOpaqueEnvelope($raw_hash);
44 }
45
46 protected function verifyPassword(
47 PhutilOpaqueEnvelope $password,
48 PhutilOpaqueEnvelope $hash) {
49 return password_verify($password->openEnvelope(), $hash->openEnvelope());
50 }
51
52 protected function canUpgradeInternalHash(PhutilOpaqueEnvelope $hash) {
53 $info = password_get_info($hash->openEnvelope());
54
55 // NOTE: If the costs don't match -- even if the new cost is lower than
56 // the old cost -- count this as an upgrade. This allows costs to be
57 // adjusted down and hashing to be migrated toward the new cost if costs
58 // are ever configured too high for some reason.
59
60 $cost = idx($info['options'], 'cost');
61 if ($cost != $this->getBcryptCost()) {
62 return true;
63 }
64
65 return false;
66 }
67
68 private function getBcryptCost() {
69 // NOTE: The default cost is "10", but my laptop can do a hash of cost
70 // "12" in about 300ms. Since server hardware is often virtualized or old,
71 // just split the difference.
72 return 11;
73 }
74
75}