← Home ← Codex ← DEBT
Browse by Category
+ added · updated 7d
← Back to glossary

Hashing Algorithms Deep Dive

Algorithms PHP 7.2+ Intermediate
debt(d5/e3/b3/t7)
d5 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'specialist tool catches it' (d5), because detection_hints lists semgrep, psalm, and phpstan with a code_pattern targeting md5()/sha1() in security contexts. These are not default linters but specialist static analysis tools that must be configured to catch the pattern — the misuse won't surface from a basic syntax or default linter check.

e3 Effort Remediation debt — work required to fix once spotted

Closest to 'simple parameterised fix' (e3), because the quick_fix is essentially a function-name swap (md5→SHA-256, SHA-1→BLAKE3, plain hash→Argon2id/HMAC-SHA256). Each individual misuse is a targeted replacement within a small number of call sites, but across an entire codebase multiple files may need touching, keeping it from being a pure e1 single-line patch.

b3 Burden Structural debt — long-term weight of choosing wrong

Closest to 'localised tax' (b3), because the choice of hash function is typically scoped to specific subsystems (auth, file integrity, caching). It applies to web/cli/queue contexts but doesn't impose a cross-cutting gravitational pull on every future change — once corrected in the relevant component, the rest of the codebase is largely unaffected.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap' (t7), because the misconception is a direct contradiction of developer intuition: 'faster is better' is correct in almost every other performance context, but for passwords slower is explicitly correct. This contradicts how performance optimization reasoning works elsewhere, and the common_mistakes show four distinct real-world failure modes (password hashing, checksum misuse, collision attacks, security forgery) — a competent developer new to the domain will almost certainly guess wrong.

About DEBT scoring →

Also Known As

xxHash MurmurHash BLAKE3 CRC32 hash function comparison

TL;DR

Comparing hash functions for different use cases — MD5/SHA-1 (broken, legacy), SHA-256/BLAKE3 (data integrity), bcrypt/Argon2 (passwords), xxHash/MurmurHash (non-cryptographic, fast).

Explanation

Hash functions serve different purposes: Cryptographic hashes (SHA-256, SHA-3, BLAKE3) — collision and pre-image resistant, for data integrity and HMACs. Password hashing (bcrypt, Argon2id, scrypt) — deliberately slow, memory-hard, salted. Non-cryptographic hashes (xxHash, MurmurHash, CRC32) — extremely fast, not collision-resistant, for hash tables and checksums where security is not required. MD5 and SHA-1 are broken (collision attacks demonstrated) — never use for security. PHP: hash() for cryptographic, password_hash() for passwords, crc32() for non-security checksums.

Common Misconception

A faster hash is always better — for passwords, slower is better (bcrypt cost factor); for HMACs, speed with security is the goal (SHA-256); for hash tables, pure speed wins (xxHash).

Why It Matters

Using SHA-256 for passwords (fast algorithm) is wrong; using bcrypt for a hash table (slow) is wrong — matching the hash function to the use case is the critical decision.

Common Mistakes

  • SHA-256 or MD5 for passwords — fast algorithms, GPU-crackable at billions per second.
  • bcrypt for non-security checksums — 400ms per hash where 1 microsecond is sufficient.
  • MD5 for file integrity — collision attacks allow two different files with the same MD5.
  • CRC32 for security applications — CRC32 is not cryptographic and easily forged.

Code Examples

✗ Vulnerable
// Wrong hash for the job:
$passwordHash = hash('sha256', $password);  // GPU-crackable in seconds
$checksum     = password_hash($data, PASSWORD_BCRYPT); // 400ms for a file checksum!
$fileInteg    = md5_file($upload);          // Collision-vulnerable integrity check
✓ Fixed
// Right hash for each use case:

// Passwords — slow, memory-hard:
$passwordHash = password_hash($password, PASSWORD_ARGON2ID);

// File integrity — cryptographic, collision-resistant:
$checksum = hash_file('sha256', $uploadPath);

// HMAC — authenticated integrity:
$mac = hash_hmac('sha256', $message, $secretKey);

// Cache key (non-security) — fast:
$cacheKey = 'page:' . crc32($url . $queryString); // Fast, not security

// Constant-time comparison for all security-sensitive comparisons:
if (!hash_equals($expected, $computed)) throw new SecurityException();

Added 16 Mar 2026
Edited 5 Apr 2026
Views 59
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 2 pings W 1 ping T 1 ping F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 1 ping F 1 ping S 2 pings S 1 ping M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 1 ping T 1 ping W 0 pings T 0 pings F 1 ping S 2 pings S 0 pings M 0 pings T 0 pings W
No pings yet today
No pings yesterday
Amazonbot 9 Ahrefs 5 Scrapy 5 Perplexity 4 SEMrush 4 Unknown AI 2 Google 2 Claude 2 ChatGPT 2 PetalBot 2 Majestic 1 Meta AI 1 Bing 1
crawler 37 crawler_json 3
DEV INTEL Tools & Severity
🟠 High ⚙ Fix effort: Low
⚡ Quick Fix
MD5 and SHA1 are cryptographically broken — use SHA-256 for checksums, SHA-3 or BLAKE3 for new systems, Argon2id for passwords, and HMAC-SHA256 for message authentication
📦 Applies To
PHP 7.2+ any web cli queue-worker
🔗 Prerequisites
🔍 Detection Hints
md5() or sha1() for security: integrity checks token generation signatures; hash without salt for password
Auto-detectable: ✓ Yes semgrep psalm phpstan
⚠ Related Problems
🤖 AI Agent
Confidence: High False Positives: Low ✓ Auto-fixable Fix: Low Context: Line
CWE-327 CWE-328


✓ schema.org compliant