php-standard-library/hash
Cryptographic and non-cryptographic hashing for PHP with an Algorithm enum, timing-safe comparison, and HMAC support.
Architecture fit
Hash facade rather than replacing it. Laravel's Hash is password-oriented (bcrypt/argon2 via password_hash()); this package covers the other 80% of hashing work that teams improvise — cache keys, ETags, file checksums, dedupe keys, webhook signatures, HMAC tokens.Algorithm enum, one HMAC entry point, and one timing-safe comparator. Everything under it is a thin wrapper over ext-hash (hash(), hash_hmac(), hash_equals()), which Laravel already exposes natively. A TPM should frame the business case as "eliminate ad-hoc hashing variants across the codebase and audit logs," not "add hashing we don't have."Algorithm enum is the strongest architectural hook: it makes algorithm choice a code-reviewable artifact and a candidate for static-analysis rules (ban bare md5()/sha1()), which is how the standard actually gets enforced.Integration feasibility
hash key. Laravel already binds hash to Illuminate\Hashing\HashManager; overwriting it silently breaks password hashing and anything resolving Hash from the container. Use a distinct key (hash.standard, HashGenerator::class) and a distinct facade alias.Technical risk
hash_hmac with $raw_output/binary key handling).Algorithm cases actually resolve depends on hash_algos() on the runtime image (xxHash family, blake3-class algorithms vary by PHP build). Enum ergonomics can create an illusion of portability across services that does not exist.Hash/password_hash() path, permanently.Key questions
hash_equals() semantics exactly, including unequal-length input handling? Any length-dependent early exit is a vulnerability, not a style issue.hash_algos())?Hasher class with a backed enum? If the answer is "a maintained implementation," that claim needs evidence this package can't currently supply.Stack fit
ext-hash, ext-sodium, or Laravel's Hash manager. Compatible with Octane and long-running workers (stateless, no mutable global configuration surface described).Hash → passwords and anything password_verify-shaped. This package → everything else (checksums, cache keys, HMAC signatures, token comparison, PII tokenization for logs).Migration path
md5(, sha1(, crc32(, hash(, hash_hmac(, ==/=== on tokens, and hand-rolled comparison loops. Produce a call-site table with data classification (does a stored value depend on the output?).md5()/sha1() and on non-constant-time token comparison. This is where the standard actually sticks; without it, the package is optional decoration.Compatibility
Algorithm case resolves on every runtime image (local, CI, staging, prod containers) — not just on a developer machine.PackageOutput === native_function_output per algorithm, including binary input, empty string, and multi-megabyte payloads.Sequencing
composer.json with the lockfile committed and the package recorded in the SBOM.Maintenance
^6. Budget for fork-and-vendor: at this adoption level, assume the fork is the contingency and pre-verify that the source is small enough to carry (it should be).ext-hash.Support
Algorithm, generate, compare/verify). The support cost is concentrated in policy questions ("which algorithm here?") rather than bug triage.hash()/hash_equals() behind the same internal interface, which is why an internal interface is worth having even if it just delegates to this package.Scaling
Failure modes
| Failure | Blast radius | Detection | Mitigation |
|---|---|---|---|
| Output drift after upgrade/algorithm change | High — invalidates stored checksums, cache keys, signatures; auth failures or silent cache misses | Parity contract tests in CI; signature conformance tests | Version pin; never change algorithm in place — version the key/prefix |
Timing-safe comparator misused (=== instead of the comparator) |
High — side-channel exposure | Static analysis rule; targeted security test | Enforce via CI lint, not docs |
| Wrong algorithm selected (MD5 in a security-relevant path) | Medium–High | Code review against the enum decision table | Publish an approved-algorithm matrix; default to SHA-256 |
| Algorithm unavailable on host | Medium — runtime exception in prod only | Container smoke test enumerating required cases | Assert hash_algos() coverage at boot/deploy |
| Upstream abandonment or compromised release | Medium (High if unvetted) | Packagist monitoring; pinned tags | Fork, vendor, internal review gate before any version bump |
Overwriting Laravel's hash container binding |
High — breaks password hashing app-wide | Integration test on auth flows | Distinct binding key and facade alias |
Ramp-up
Hash vs. hash_equals directly. That's a one-page doc plus one review cycle, and it is the single highest-leverage artifact in the whole adoption.hash_algos(), quantum-resistant requirements — so the boundary is decided once rather than per pull request.How can I help you explore Laravel packages today?