diff --git a/4dev/tests/Create/CoreLibsCreateHashTest.php b/4dev/tests/Create/CoreLibsCreateHashTest.php index 4eb7e694..9ce36b35 100644 --- a/4dev/tests/Create/CoreLibsCreateHashTest.php +++ b/4dev/tests/Create/CoreLibsCreateHashTest.php @@ -21,8 +21,10 @@ final class CoreLibsCreateHashTest extends TestCase public function hashData(): array { return [ - 'any string' => [ + 'hash tests' => [ + // this is the string 'text' => 'Some String Text', + // hash list special 'crc32b_reverse' => 'c5c21d91', // crc32b (in revere) 'sha1Short' => '4d2bc9ba0', // sha1Short // via hash @@ -31,6 +33,8 @@ final class CoreLibsCreateHashTest extends TestCase 'fnv132' => '9df444f9', // hash: fnv132 'fnv1a32' => '2c5f91b9', // hash: fnv1a32 'joaat' => '50dab846', // hash: joaat + 'ripemd160' => 'aeae3f041b20136451519edd9361570909300342', // hash: ripemd160, + 'sha256' => '9055080e022f224fa835929b80582b3c71c672206fa3a49a87412c25d9d42ceb', // hash: sha256 ] ]; } @@ -81,7 +85,7 @@ final class CoreLibsCreateHashTest extends TestCase { $list = []; foreach ($this->hashData() as $name => $values) { - foreach ([null, 'crc32b', 'adler32', 'fnv132', 'fnv1a32', 'joaat'] as $_hash_type) { + foreach ([null, 'crc32b', 'adler32', 'fnv132', 'fnv1a32', 'joaat', 'ripemd160', 'sha256'] as $_hash_type) { // default value test if ($_hash_type === null) { $hash_type = \CoreLibs\Create\Hash::STANDARD_HASH_SHORT; @@ -288,7 +292,7 @@ final class CoreLibsCreateHashTest extends TestCase * Undocumented function * * @covers ::hash - * @testdox hash with invalid type [$_dataName] + * @testdox hash with invalid type * * @return void */ @@ -301,6 +305,122 @@ final class CoreLibsCreateHashTest extends TestCase \CoreLibs\Create\Hash::hash($hash_source, 'DOES_NOT_EXIST') ); } + + /** + * Note: this only tests default sha256 + * + * @covers ::hashHmac + * @testdox hash hmac test + * + * @return void + */ + public function testHashMac(): void + { + $hash_key = 'FIX KEY'; + $hash_source = 'Some String Text'; + $expected = '16479b3ef6fa44e1cdd8b2dcfaadf314d1a7763635e8738f1e7996d714d9b6bf'; + $this->assertEquals( + $expected, + \CoreLibs\Create\Hash::hashHmac($hash_source, $hash_key) + ); + } + + /** + * Undocumented function + * + * @covers ::hashHmac + * @testdox hash hmac with invalid type + * + * @return void + */ + public function testInvalidHashMacType(): void + { + $hash_key = 'FIX KEY'; + $hash_source = 'Some String Text'; + $expected = hash_hmac(\CoreLibs\Create\Hash::STANDARD_HASH, $hash_source, $hash_key); + $this->assertEquals( + $expected, + \CoreLibs\Create\Hash::hashHmac($hash_source, $hash_key, 'DOES_NOT_EXIST') + ); + } + + /** + * Undocumented function + * + * @return array + */ + public function providerHashTypes(): array + { + return [ + 'Hash crc32b' => [ + 'crc32b', + true, + false, + ], + 'Hash adler32' => [ + 'adler32', + true, + false, + ], + 'HAsh fnv132' => [ + 'fnv132', + true, + false, + ], + 'Hash fnv1a32' => [ + 'fnv1a32', + true, + false, + ], + 'Hash: joaat' => [ + 'joaat', + true, + false, + ], + 'Hash: ripemd160' => [ + 'ripemd160', + true, + true, + ], + 'Hash: sha256' => [ + 'sha256', + true, + true, + ], + 'Hash: invalid' => [ + 'invalid', + false, + false + ] + ]; + } + + /** + * Undocumented function + * + * @covers ::isValidHashType + * @covers ::isValidHashHmacType + * @dataProvider providerHashTypes + * @testdox check if $hash_type is valid for hash $hash_ok and hash hmac $hash_hmac_ok [$_dataName] + * + * @param string $hash_type + * @param bool $hash_ok + * @param bool $hash_hmac_ok + * @return void + */ + public function testIsValidHashAndHashHmacTypes(string $hash_type, bool $hash_ok, bool $hash_hmac_ok): void + { + $this->assertEquals( + $hash_ok, + \CoreLibs\Create\Hash::isValidHashType($hash_type), + 'hash valid' + ); + $this->assertEquals( + $hash_hmac_ok, + \CoreLibs\Create\Hash::isValidHashHmacType($hash_type), + 'hash hmac valid' + ); + } } // __END__ diff --git a/www/admin/class_test.hash.php b/www/admin/class_test.hash.php index 0d78175d..34ae3830 100644 --- a/www/admin/class_test.hash.php +++ b/www/admin/class_test.hash.php @@ -19,6 +19,7 @@ $LOG_FILE_ID = 'classTest-hash'; ob_end_flush(); use CoreLibs\Create\Hash; +use CoreLibs\Security\CreateKey; $log = new CoreLibs\Logging\Logging([ 'log_folder' => BASE . LOG, @@ -53,10 +54,14 @@ print "U-S::__CRC32B: $to_crc: " . Hash::__crc32b($to_crc) . "
"; echo "
"; $text = 'Some String Text'; +// $text = 'any string'; $type = 'crc32b'; print "Hash: " . $type . ": " . hash($type, $text) . "
"; // print "Class (old): " . $type . ": " . Hash::__hash($text, $type) . "
"; print "Class (new): " . $type . ": " . Hash::hash($text, $type) . "
"; +print "Class: sha256: " . Hash::hash($text) . "
"; +$type = 'ripemd160'; +print "Class: " . $type . ": " . Hash::hash($text, $type) . "
"; echo "
"; print "CURRENT STANDARD_HASH_SHORT: " . Hash::STANDARD_HASH_SHORT . "
"; @@ -66,6 +71,31 @@ print "HASH SHORT: " . $to_crc . ": " . Hash::hashShort($to_crc) . "
"; print "HASH LONG: " . $to_crc . ": " . Hash::hashLong($to_crc) . "
"; print "HASH DEFAULT: " . $to_crc . ": " . Hash::hashStd($to_crc) . "
"; +echo "
"; +$key = CreateKey::generateRandomKey(); +$key = "FIX KEY"; +print "Secret Key: " . $key . "
"; +print "HASHMAC DEFAULT (fix): " . $to_crc . ": " . Hash::hashHmac($to_crc, $key) . "
"; +$key = CreateKey::generateRandomKey(); +print "Secret Key: " . $key . "
"; +print "HASHMAC DEFAULT (random): " . $to_crc . ": " . Hash::hashHmac($to_crc, $key) . "
"; + +echo "
"; +$hash_types = ['crc32b', 'sha256', 'invalid']; +foreach ($hash_types as $hash_type) { + echo "Checking $hash_type:
"; + if (Hash::isValidHashType($hash_type)) { + echo "hash type: $hash_type is valid
"; + } else { + echo "hash type: $hash_type is INVALID
"; + } + if (Hash::isValidHashHmacType($hash_type)) { + echo "hash hmac type: $hash_type is valid
"; + } else { + echo "hash hmac type: $hash_type is INVALID
"; + } +} + // print "UNIQU ID SHORT : " . Hash::__uniqId() . "
"; // print "UNIQU ID LONG : " . Hash::__uniqIdLong() . "
"; diff --git a/www/lib/CoreLibs/Create/Hash.php b/www/lib/CoreLibs/Create/Hash.php index e408f7d3..9ed734db 100644 --- a/www/lib/CoreLibs/Create/Hash.php +++ b/www/lib/CoreLibs/Create/Hash.php @@ -49,7 +49,7 @@ class Hash * replacement for __crc32b call * * @param string $string string to hash - * @param bool $use_sha use sha1 instead of crc32b (default false) + * @param bool $use_sha [default=false] use sha1 instead of crc32b * @return string hash of the string * @deprecated use __crc32b() for drop in replacement with default, or sha1Short() for use sha true */ @@ -81,7 +81,7 @@ class Hash * all that create 8 char long hashes * * @param string $string string to hash - * @param string $hash_type hash type (default adler32) + * @param string $hash_type [default=STANDARD_HASH_SHORT] hash type (default adler32) * @return string hash of the string * @deprecated use hashShort() of short hashes with adler 32 or hash() for other hash types */ @@ -92,12 +92,40 @@ class Hash return self::hash($string, $hash_type); } + /** + * check if hash type is valid, returns false if not + * + * @param string $hash_type + * @return bool + */ + public static function isValidHashType(string $hash_type): bool + { + if (!in_array($hash_type, hash_algos())) { + return false; + } + return true; + } + + /** + * check if hash hmac type is valid, returns false if not + * + * @param string $hash_hmac_type + * @return bool + */ + public static function isValidHashHmacType(string $hash_hmac_type): bool + { + if (!in_array($hash_hmac_type, hash_hmac_algos())) { + return false; + } + return true; + } + /** * creates a hash over string if any valid hash given. * if no hash type set use sha256 * - * @param string $string string to ash - * @param string $hash_type hash type (default sha256) + * @param string $string string to hash + * @param string $hash_type [default=STANDARD_HASH] hash type (default sha256) * @return string hash of the string */ public static function hash( @@ -108,12 +136,36 @@ class Hash empty($hash_type) || !in_array($hash_type, hash_algos()) ) { - // fallback to default hash type if none set or invalid + // fallback to default hash type if empty or invalid $hash_type = self::STANDARD_HASH; } return hash($hash_type, $string); } + /** + * creates a hash mac key + * + * @param string $string string to hash mac + * @param string $key key to use + * @param string $hash_type [default=STANDARD_HASH] + * @return string hash mac string + */ + public static function hashHmac( + string $string, + #[\SensitiveParameter] + string $key, + string $hash_type = self::STANDARD_HASH + ): string { + if ( + empty($hash_type) || + !in_array($hash_type, hash_hmac_algos()) + ) { + // fallback to default hash type if e or invalid + $hash_type = self::STANDARD_HASH; + } + return hash_hmac($hash_type, $string, $key); + } + /** * short hash with max length of 8, uses adler32 *