1313
1414
1515/**
16- * Passwords tools .
16+ * Password Hashing .
1717 */
1818class Passwords
1919{
20- use Nette \StaticClass;
20+ use Nette \SmartObject;
21+
22+ /** @var int */
23+ private $ algo ;
24+
25+ /** @var array */
26+ private $ options ;
27+
2128
2229 /**
23- * Computes salted password hash. Accepts option 'cost' (4-31)
30+ * See http://php.net/manual/en/ password.constants.php
2431 */
25- public static function hash ( string $ password , array $ options = []): string
32+ public function __construct ( int $ algo = PASSWORD_DEFAULT , array $ options = [])
2633 {
27- if (isset ($ options ['cost ' ]) && ($ options ['cost ' ] < 4 || $ options ['cost ' ] > 31 )) {
28- throw new Nette \InvalidArgumentException ("Cost must be in range 4-31, $ options [cost] given. " );
29- }
34+ $ this ->algo = $ algo ;
35+ $ this ->options = $ options ;
36+ }
37+
38+
39+ /**
40+ * Computes salted password hash.
41+ */
42+ public function hash (string $ password ): string
43+ {
44+ $ hash = isset ($ this )
45+ ? @password_hash ($ password , $ this ->algo , $ this ->options ) // @ is escalated to exception
46+ : @password_hash ($ password , PASSWORD_BCRYPT , func_get_args ()[1 ] ?? []); // back compatibility with v2.x
3047
31- $ hash = password_hash ($ password , PASSWORD_BCRYPT , $ options );
32- if ($ hash === false || strlen ($ hash ) < 60 ) {
33- throw new Nette \InvalidStateException ('Hash computed by password_hash is invalid. ' );
48+ if (!$ hash ) {
49+ throw new Nette \InvalidStateException ('Computed hash is invalid. ' . error_get_last ()['message ' ]);
3450 }
3551 return $ hash ;
3652 }
@@ -39,17 +55,19 @@ public static function hash(string $password, array $options = []): string
3955 /**
4056 * Verifies that a password matches a hash.
4157 */
42- public static function verify (string $ password , string $ hash ): bool
58+ public function verify (string $ password , string $ hash ): bool
4359 {
4460 return password_verify ($ password , $ hash );
4561 }
4662
4763
4864 /**
49- * Checks if the given hash matches the options. Accepts option 'cost' (4-31)
65+ * Checks if the given hash matches the options.
5066 */
51- public static function needsRehash (string $ hash, array $ options = [] ): bool
67+ public function needsRehash (string $ hash ): bool
5268 {
53- return password_needs_rehash ($ hash , PASSWORD_BCRYPT , $ options );
69+ return isset ($ this )
70+ ? password_needs_rehash ($ hash , $ this ->algo , $ this ->options )
71+ : password_needs_rehash ($ hash , PASSWORD_BCRYPT , func_get_args ()[1 ] ?? []); // back compatibility with v2.x
5472 }
5573}
0 commit comments