November 30, 2016 —John Koster
In this article we will create an implementation of Illuminate\Contracts\Hashing\Hasher
using PHP's crypt
function and the CRYPT_MD5
hashing function. Like in the previous sections, we will examine each method before looking at the full implementation.
make($value, array $options = [])
The make
method is responsible for doing the actual hashing. It also accepts an $options
array. We will allow an eight character long salt to be supplied using the options array. If no salt is supplied, we will generate one.
For the actual hashing, we will make a call to PHP's crypt
function.
public function check($value, $hashedValue, array $options = [])
The check
method is used to check that a known $value
is the same as a given $hashedValue
. We will not need any options for this method.
For the actual hashing, we will use PHP's crypt
function.
public function needsRehash($hashedValue, array $options = [])
The needsRehash
method is used to determine if a given hash needs to be updated, or rehashed. We will accept a salt as an option. If the salt from the $options
array does not match the salt from the $hashedValue
the $hashedValue
needs to be rehashed.
MD5Hasher Options | Description |
---|---|
salt |
A salt can be supplied to the make and needsRehash methods. If no salt is supplied to the make method, one will be generated. |
The following is the complete implementation of the Md5Hasher
class:
1<?php 2 3namespace Laravel\Artisan\Hashing; 4 5use RuntimeException; 6use Illuminate\Contracts\Hashing\Hasher as HasherContract; 7use Illuminate\Support\Str; 8 9class Md5Hasher implements HasherContract10{11 12 const FAILED_HASH = '*0';13 14 /**15 * Hash the given value.16 *17 * @param string $value18 * @param array $options19 * @return string20 *21 * @throws \RuntimeException22 */23 public function make($value, array $options = [])24 {25 // If the user supplied a salt, use that. If not we26 // can generate it using the Str helper methods.27 $salt = isset($options['salt']) ?28 $options['salt'] : Str::random(8);29 30 $salt = '$1$'.$salt.'$';31 32 $hash = crypt($value, $salt);33 34 if ($hash == self::FAILED_HASH) {35 // Throw an exception because the hashing failed.36 throw new RuntimeException('MD5 hashing failed.');37 }38 39 return $hash;40 }41 42 /**43 * Check the given plain value against a hash.44 *45 * @param string $value46 * @param string $hashedValue47 * @param array $options48 * @return bool49 */50 public function check($value, $hashedValue, array $options = [])51 {52 // Let's get the salt from the $hashedValue so we can hash53 // $value using the same exact salt as $hashedValue.54 $salt = mb_substr($hashedValue, 3, 8);55 $userValue = $this->make($value, ['salt' => $salt]);56 57 return hash_equals($hashedValue, $userValue);58 }59 60 /**61 * Check if the given hash has been hashed using the given options.62 *63 * @param string $hashedValue64 * @param array $options65 * @return bool66 */67 public function needsRehash($hashedValue, array $options = [])68 {69 if (!isset($options['salt'])) {70 return false;71 }72 73 return (substr($hashedValue, 3, 8) !== $options['salt']);74 }75 76}
∎
The following amazing people help support this site and my open source projects ♥️
If you're interesting in supporting my work and want to show up on this list, check out my GitHub Sponsors Profile.