@@ -46,14 +46,18 @@ public function __construct(string $algorithm)
4646 *
4747 * If the return value matches $pw_db, then the plain text password ('pw') is correct.
4848 *
49- * @param string $pw - plain text password
50- * @param string $pw_db - hash from e.g. database (what we're comparing $pw to).
49+ * @param string $clearText - plain text password
50+ * @param ? string $passwordHash - hash from e.g. database (what we're comparing $pw to).
5151 * @return string if $pw is correct (hashes to $pw_db) then we return $pw_db. Else we return a new hash.
5252 *
5353 * @throws Exception
5454 */
55- public function crypt (string $ clearText , string $ passwordHash = null ): string
55+ public function crypt (string $ clearText , ? string $ passwordHash = null ): string
5656 {
57+ if (is_string ($ passwordHash ) && empty ($ passwordHash )) {
58+ $ passwordHash = null ;
59+ }
60+
5761 $ algorithm = $ this ->algorithm ;
5862
5963 switch ($ this ->algorithm ) {
@@ -114,11 +118,11 @@ public function crypt(string $clearText, string $passwordHash = null): string
114118
115119 case 'CRYPT ' :
116120 $ prefix = false ;
117- if (!empty ($ passwordHash )) {
121+ if (!is_null ($ passwordHash )) {
118122 $ prefix = (substr ($ passwordHash , 0 , 7 ) == '{CRYPT} ' );
119123 $ passwordHash = preg_replace ('/^{CRYPT}/ ' , '' , $ passwordHash );
120124 }
121- if (empty ($ passwordHash )) {
125+ if (is_null ($ passwordHash )) {
122126 $ passwordHash = '$2y$10$ ' . substr (sha1 (random_bytes (8 )), 0 , 22 );
123127 }
124128 $ str = crypt ($ clearText , $ passwordHash );
@@ -159,27 +163,31 @@ public function hashSha1(string $clearText, string $algorithm = 'SHA1'): string
159163 return "{ {$ algorithm }} {$ hash }" ;
160164 }
161165
162- public function hashSha1Salted (string $ clearText , string $ hash = null ): string
166+ public function hashSha1Salted (string $ clearText , ? string $ hash = null ): string
163167 {
164- if (empty ($ hash )) {
168+ $ hash = $ this ->changeEmptyHashToNull ($ hash );
169+
170+ if (is_null ($ hash )) {
165171 $ salt = base64_encode (random_bytes (3 )); // 4 char salt.
166172 } else {
167173 $ salt = substr (base64_decode (substr ($ hash , 6 )), 20 );
168174 }
169175 return '{SSHA} ' . base64_encode (sha1 ($ clearText . $ salt , true ) . $ salt );
170176 }
171177
172- public function hashSha512Salted (string $ clearText , string $ hash = null ): string
178+ public function hashSha512Salted (string $ clearText , ? string $ hash = null ): string
173179 {
174- if (empty ($ hash )) {
180+ $ hash = $ this ->changeEmptyHashToNull ($ hash );
181+
182+ if (is_null ($ hash )) {
175183 $ salt = base64_encode (random_bytes (16 ));
176184 } else {
177185 $ salt = substr (base64_decode (substr ($ hash , 9 )), 64 );
178186 }
179187 return '{SSHA512} ' . base64_encode (hash ('sha512 ' , $ clearText . $ salt , true ) . $ salt );
180188 }
181189
182- public function hashSha512 (string $ clearText , string $ algorithm = 'SHA512 ' )
190+ public function hashSha512 (string $ clearText , string $ algorithm = 'SHA512 ' ): string
183191 {
184192 $ prefix = '{SHA512} ' ;
185193
@@ -203,20 +211,24 @@ public function hashSha256(string $clearText): string
203211 return '{SHA256} ' . base64_encode (hash ('sha256 ' , $ clearText , true ));
204212 }
205213
206- public function cryptMd5 (string $ clearText , string $ hash = null , $ algorithm = 'MD5-CRYPT ' )
214+ public function cryptMd5 (string $ clearText , ? string $ hash = null , string $ algorithm = 'MD5-CRYPT ' ): string
207215 {
208- if (!empty ($ hash )) {
216+ $ hash = $ this ->changeEmptyHashToNull ($ hash );
217+
218+ if (is_string ($ hash )) {
209219 $ hash = preg_replace ('/^{MD5.*}/ ' , '' , $ hash );
210220 }
211- if (empty ($ hash )) {
221+ if (is_null ($ hash )) {
212222 $ hash = '$1$ ' . substr (sha1 (random_bytes (8 )), 0 , 16 );
213223 }
214224 return "{ {$ algorithm }} " . crypt ($ clearText , $ hash );
215225 }
216226
217- public function blowfishCrypt (string $ clearText , string $ hash = null , string $ algorithm = 'BLF-CRYPT ' ): string
227+ public function blowfishCrypt (string $ clearText , ? string $ hash = null , string $ algorithm = 'BLF-CRYPT ' ): string
218228 {
219- if (!empty ($ hash )) {
229+ $ hash = $ this ->changeEmptyHashToNull ($ hash );
230+
231+ if (is_string ($ hash )) {
220232 if ($ algorithm == 'BLF-CRYPT ' ) {
221233 $ hash = preg_replace ('/^{BLF-CRYPT}/ ' , '' , $ hash );
222234 }
@@ -244,17 +256,19 @@ public function blowfishCrypt(string $clearText, string $hash = null, string $al
244256 return '{BLF-CRYPT} ' . $ r ;
245257 }
246258
247- public function sha256Crypt (string $ clearText , string $ hash = null , string $ algorithm = 'SHA256-CRYPT ' ): string
259+ public function sha256Crypt (string $ clearText , ? string $ hash = null , string $ algorithm = 'SHA256-CRYPT ' ): string
248260 {
249- if (!empty ($ hash )) {
261+ $ hash = $ this ->changeEmptyHashToNull ($ hash );
262+
263+ if (is_string ($ hash )) {
250264 $ hash = preg_replace ('/^{SHA256-CRYPT(\.B64)?}/ ' , '' , $ hash );
251265
252266 if ($ algorithm == 'SHA256-CRYPT.B64 ' ) {
253267 $ hash = base64_decode ($ hash );
254268 }
255269 }
256270
257- if (empty ($ hash )) {
271+ if (is_null ($ hash )) {
258272 $ hash = '$5$ ' . substr (sha1 (random_bytes (8 )), 0 , 16 );
259273 }
260274
@@ -266,17 +280,19 @@ public function sha256Crypt(string $clearText, string $hash = null, string $algo
266280 return "{SHA256-CRYPT} " . $ generated ;
267281 }
268282
269- public function sha512Crypt (string $ pw , string $ hash = null , string $ algorithm = 'SHA512-CRYPT ' ): string
283+ public function sha512Crypt (string $ pw , ? string $ hash = null , string $ algorithm = 'SHA512-CRYPT ' ): string
270284 {
271- if (!empty ($ hash )) {
285+ $ hash = $ this ->changeEmptyHashToNull ($ hash );
286+
287+ if (is_string ($ hash )) {
272288 $ hash = preg_replace ('/^{SHA512-CRYPT(\.B64)?}/ ' , '' , $ hash );
273289
274290 if ($ algorithm == 'SHA512-CRYPT.B64 ' ) {
275291 $ hash = base64_decode ($ hash );
276292 }
277293 }
278294
279- if (empty ($ hash )) {
295+ if (is_null ($ hash )) {
280296 $ hash = '$6$ ' . substr (sha1 (random_bytes (8 )), 0 , 16 );
281297 }
282298
@@ -290,9 +306,17 @@ public function sha512Crypt(string $pw, string $hash = null, string $algorithm =
290306 return "{SHA512-CRYPT} $ generated " ;
291307 }
292308
293- public function argon2ICrypt (string $ clearText , string $ hash = null , $ algorithm = 'ARGON2I ' ): string
309+ /**
310+ * @param string $clearText
311+ * @param string|null $hash
312+ * @param $algorithm
313+ * @return string
314+ */
315+ public function argon2ICrypt (string $ clearText , ?string $ hash = null , string $ algorithm = 'ARGON2I ' ): string
294316 {
295- if (!empty ($ hash )) {
317+ $ hash = $ this ->changeEmptyHashToNull ($ hash );
318+
319+ if (is_string ($ hash )) {
296320 $ hash = preg_replace ('/^{ARGON2I(\.B64)?}/ ' , '' , $ hash );
297321 $ orig_pwdb = $ hash ;
298322 if ($ algorithm == 'ARGON2I.B64 ' ) {
@@ -325,13 +349,15 @@ public function argon2ICrypt(string $clearText, string $hash = null, $algorithm
325349 return "{ARGON2I.B64} " . base64_encode ($ generated );
326350 }
327351
328- public function argon2idCrypt (string $ clearText , string $ hash = null , string $ algorithm = 'ARGON2ID ' ): string
352+ public function argon2idCrypt (string $ clearText , ? string $ hash = null , string $ algorithm = 'ARGON2ID ' ): string
329353 {
330354 if (!defined ('PASSWORD_ARGON2ID ' )) {
331355 throw new Exception ("$ algorithm is not supported; requires PHP 7.3+ " );
332356 }
333357
334- if (!empty ($ hash )) {
358+ $ hash = $ this ->changeEmptyHashToNull ($ hash );
359+
360+ if (is_string ($ hash )) {
335361 $ hash = preg_replace ('/^{ARGON2ID(\.B64)?}/ ' , '' , $ hash );
336362
337363 $ orig_pwdb = $ hash ;
@@ -366,4 +392,11 @@ public function argon2idCrypt(string $clearText, string $hash = null, string $al
366392 }
367393 return '{ARGON2ID.B64} ' . base64_encode ($ generated );
368394 }
395+
396+ private function changeEmptyHashToNull (?string $ hash ) : ?string {
397+ if (is_string ($ hash ) && empty ($ hash )) {
398+ return $ hash ;
399+ }
400+ return $ hash ;
401+ }
369402}
0 commit comments