VbulletinPassword::hash()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 4
ccs 3
cts 3
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * @author Todd Burry <[email protected]>
4
 * @copyright 2009-2014 Vanilla Forums Inc.
5
 * @license Proprietary
6
 */
7
8
namespace Garden\Password;
9
10
/**
11
 * Implements the vBulletin password hash algorithms.
12
 *
13
 * VBulletin itself stores password salts in a separate database column. In order to use a vBulletin password with this
14
 * class you must concatenate the salt to the end of the password hash. The vBulletin password hashing algorithm is a
15
 * poor choice for your passwords because it uses md5 which is very insecure.
16
 *
17
 * We recommend using this class to validate existing vBulletin passwords, but then rehashing them with a different
18
 * algorithm.
19
 */
20
class VbulletinPassword implements IPassword {
21
22
    /**
23
     * Hashes a plaintext password.
24
     *
25
     * @param string $password The password to hash.
26
     * @return string Returns the hashed password.
27
     */
28 3
    public function hash($password) {
29 3
        $salt = base64_encode(openssl_random_pseudo_bytes(12));
30 3
        return $this->hashRaw($password, $salt).$salt;
31
    }
32
33 4
    protected function hashRaw($password, $salt) {
34 4
        $hash = md5(md5($password).$salt);
35 4
        return $hash;
36
    }
37
38
    /**
39
     * Checks if a given password hash needs to be re-hashed to to a stronger algorithm.
40
     *
41
     * @param string $hash The hash to check.
42
     * @return bool Returns `true`
43
     */
44 1
    public function needsRehash($hash) {
45 1
        return strlen($hash) < 37;
46
    }
47
48
    /**
49
     * Check to make sure a password matches its stored hash.
50
     *
51
     * @param string $password The password to verify.
52
     * @param string $hash The stored password hash.
53
     * @return bool Returns `true` if the password matches the stored hash.
54
     */
55 3
    public function verify($password, $hash) {
56 3
        list($stored_hash, $salt) = $this->splitSalt($hash);
57 3
        $calculated_hash = $this->hashRaw($password, $salt);
58 3
        $result = $calculated_hash === $stored_hash;
59 3
        return $result;
60
    }
61
62
    /**
63
     * Split the salt and hash from a single hash.
64
     *
65
     * @param string $hash The hash to split.
66
     * @return array An array in the form `[$hash, $salt]`.
67
     */
68 3
    public function splitSalt($hash) {
69
        // The hash is in the form: <32 char hash><salt>.
70 3
        $salt_length = strlen($hash) - 32;
71 3
        $salt = trim(substr($hash, -$salt_length, $salt_length));
72 3
        $stored_hash = substr($hash, 0, strlen($hash) - $salt_length);
73
74 3
        return [$stored_hash, $salt];
75
    }
76
}
77