php-standard-library/hash
Hash utilities for PHP: cryptographic and non-cryptographic hashing via an Algorithm enum, HMAC helpers, and timing-safe string comparison. Lightweight package from PHP Standard Library for consistent, secure hashing across projects.
Installation:
composer require php-standard-library/hash
Add to composer.json under require or require-dev depending on use case.
First Usage:
use PhpStandardLibrary\Hash\HashGenerator;
$generator = new HashGenerator();
$hash = $generator->generate('my-data');
// Returns: string (e.g., "5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8")
First Laravel Integration:
// app/Providers/HashServiceProvider.php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use PhpStandardLibrary\Hash\HashGenerator;
class HashServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->singleton('hash.generator', function () {
return new HashGenerator();
});
}
}
config/app.php:
'providers' => [
// ...
App\Providers\HashServiceProvider::class,
],
Basic Laravel Usage:
$hash = app('hash.generator')->generate('user_input');
Hash facade.// For non-password data (e.g., API tokens)
$token = app('hash.generator')->generate('user_id:timestamp', 'sha256');
public function verifyFileIntegrity(string $filePath, string $expectedHash)
{
$fileBytes = file_get_contents($filePath);
$actualHash = app('hash.generator')->generate($fileBytes, 'sha512');
return $actualHash === $expectedHash;
}
HashComparator for sensitive comparisons (e.g., API keys, tokens).use PhpStandardLibrary\Hash\HashComparator;
$comparator = new HashComparator();
$isValid = $comparator->compare(
$userInput,
$storedHash,
'sha256'
);
use PhpStandardLibrary\Hash\HmacGenerator;
$hmac = new HmacGenerator('my-secret-key');
$signature = $hmac->generate('request_data');
config/hash.php:return [
'default_algorithm' => 'sha256',
'algorithms' => [
'file_checksum' => 'sha512',
'api_signature' => 'hmac-sha256',
],
];
$algorithm = config('hash.algorithms.file_checksum');
$hash = app('hash.generator')->generate($data, $algorithm);
public function handle(Request $request, Closure $next)
{
$hmac = new HmacGenerator(config('app.hmac_secret'));
$expectedSignature = $hmac->generate($request->getContent());
if (!$expectedSignature === $request->header('X-Signature')) {
abort(403, 'Invalid signature');
}
return $next($request);
}
use Illuminate\Console\Command;
use PhpStandardLibrary\Hash\HashGenerator;
class BulkHashCommand extends Command
{
protected $signature = 'hash:bulk {--file=}';
protected $description = 'Generate hashes for bulk data';
public function handle(HashGenerator $generator)
{
$data = $this->option('file') ? file($this->option('file')) : [];
foreach ($data as $item) {
$hash = $generator->generate(trim($item));
$this->line($hash);
}
}
}
public function handle(LogEvent $event)
{
$logger = new HashGenerator();
$hashedData = $logger->generate($event->data['sensitive_field']);
$event->data['sensitive_field'] = $hashedData;
}
Create a facade for cleaner syntax:
// app/Facades/Hash.php
namespace App\Facades;
use Illuminate\Support\Facades\Facade;
class Hash extends Facade
{
protected static function getFacadeAccessor()
{
return 'hash.generator';
}
}
Usage:
$hash = Hash::generate('data');
Validate algorithms against a whitelist in a trait:
trait ValidatedHashing
{
protected function validateAlgorithm(string $algorithm): void
{
$allowed = ['sha256', 'sha512', 'bcrypt', 'hmac-sha256'];
if (!in_array($algorithm, $allowed)) {
throw new \InvalidArgumentException("Algorithm {$algorithm} not allowed.");
}
}
}
Cache generated hashes to avoid recomputation:
public function getCachedHash(string $key, string $data)
{
return cache()->remember("hash:{$key}", now()->addHours(1), function () use ($data) {
return app('hash.generator')->generate($data);
});
}
HashGenerator to test hash-dependent logic.
$mockGenerator = Mockery::mock(HashGenerator::class);
$mockGenerator->shouldReceive('generate')->andReturn('mocked-hash');
$this->app->instance('hash.generator', $mockGenerator);
public function test_hash_generation()
{
$hash = Hash::generate('test');
$this->assertEquals(64, strlen($hash)); // SHA-256 length
}
hash()Replace:
// Old
$hash = hash('sha256', $data);
// New
$hash = Hash::generate($data, 'sha256');
Algorithm Confusion with Laravel’s Hash Facade:
Hash facade (for passwords) can lead to confusion.php-standard-library/hash for non-password data (e.g., tokens, checksums).Hash facade for passwords only.Timing Attacks in Custom Comparisons:
=== or == for hash comparisons can expose timing attacks.HashComparator for sensitive comparisons:
$comparator = new HashComparator();
$isValid = $comparator->compare($input, $storedHash);
Algorithm-Specific Options:
bcrypt, argon2) require additional options (e.g., cost, memory).$hash = $generator->generate('data', 'bcrypt', ['cost' => 12]);
Binary Data Handling:
$fileBytes = file_get_contents($path);
$hash = $generator->generate($fileBytes);
HMAC Key Management:
.env:
HMAC_SECRET=your_secure_key_here
$hmac = new HmacGenerator(config('app.hmac_secret'));
Deprecation of Weak Algorithms:
md5, sha1) in future updates.composer.json if relying on specific algorithms.How can I help you explore Laravel packages today?