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

Cryptographic Hash Functions

Cryptography PHP 5.1+ 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). The detection_hints list semgrep, psalm, and phpstan — these are specialist SAST/static-analysis tools, not default linters. They can flag md5()/sha1() for security use and missing HMAC patterns, but won't catch these issues without deliberate configuration and adoption of those tools.

e3 Effort Remediation debt — work required to fix once spotted

Closest to 'simple parameterised fix' (e3). The quick_fix describes choosing the right function for the use case: swap md5() for SHA-256, wrap bare hashes in hash_hmac(), replace custom hashing with password_hash(). Each fix is a targeted function-level substitution, typically within a single file or component, not a cross-cutting architectural change.

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

Closest to 'localised tax' (b3). The misuse affects whichever component handles hashing (password storage, file checksums, message authentication), but doesn't structurally reshape the entire codebase. Once corrected in the relevant module, the rest of the system is largely unaffected. The applies_to scope covers web/cli/queue but the actual hashing logic is usually concentrated in a few locations.

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

Closest to 'serious trap' (t7). The misconception field captures the canonical wrong belief: SHA-256 looks like a strong, modern cryptographic hash and a competent developer naturally assumes it is suitable for passwords — but it is precisely its speed (billions of ops/second on a GPU) that makes it catastrophically wrong for that use case. This contradicts intuition from general crypto knowledge, where 'stronger/newer' implies 'better for all uses'. The timing-attack trap (== vs hash_equals()) compounds this, making t7 appropriate.

About DEBT scoring →

Also Known As

SHA-256 SHA-3 BLAKE3 MD5 SHA-1 cryptographic hash

TL;DR

One-way functions producing a fixed-length digest — SHA-256, SHA-3, and BLAKE3 are secure for data integrity; MD5 and SHA-1 are broken and must not be used for security.

Explanation

Cryptographic hash functions must be: deterministic (same input = same output), fast to compute, pre-image resistant (cannot reverse), second pre-image resistant (cannot find collision for a given input), and collision resistant (cannot find any two inputs with the same hash). SHA-256/SHA-512 (SHA-2 family): widely deployed, no known practical attacks. SHA-3 (Keccak): different construction, quantum-resistant design. BLAKE3: fast, secure, modern. MD5 and SHA-1: broken collision resistance — do not use for security. In PHP: hash('sha256', $data), hash('sha3-256', $data).

Common Misconception

SHA-256 is suitable for password hashing — SHA-256 is fast (billions of operations per second on a GPU), making it unusable for passwords; use bcrypt or Argon2id instead.

Why It Matters

Using MD5 or SHA-1 for data integrity checks opens the door to collision attacks where two different inputs produce the same hash — file signature forgery and certificate attacks both exploit this.

Common Mistakes

  • MD5 for file integrity checksums — collisions have been demonstrated; use SHA-256.
  • SHA-256 for password hashing — fast algorithm; use password_hash() with Argon2id.
  • Not using HMAC for message authentication — a bare hash can be length-extended; use hash_hmac().
  • Comparing hashes with == instead of hash_equals() — timing attack vulnerability.

Code Examples

✗ Vulnerable
// MD5 for integrity — broken:
$checksum = md5_file($uploadedFile); // Collisions possible

// SHA-256 for password — wrong tool:
$hash = hash('sha256', $password); // Fast = GPU crackable

// Timing-vulnerable comparison:
if ($computed === $provided) { /* vulnerable to timing attack */ }
✓ Fixed
// SHA-256 for file integrity:
$checksum = hash_file('sha256', $uploadedFile); // Secure for integrity

// Argon2id for passwords:
$hash = password_hash($password, PASSWORD_ARGON2ID);

// HMAC for message authentication:
$mac = hash_hmac('sha256', $message, $secretKey);

// Constant-time comparison:
if (hash_equals($expected, $computed)) { /* safe */ }

Added 16 Mar 2026
Edited 22 Mar 2026
Views 66
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 0 pings W 1 ping T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 1 ping T 2 pings F 2 pings S 7 pings S 3 pings M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S 0 pings S 1 ping M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 1 ping S 1 ping M 1 ping T 0 pings W
No pings yet today
PetalBot 1
Amazonbot 15 Scrapy 14 SEMrush 5 Google 4 Perplexity 4 Ahrefs 4 Majestic 2 Unknown AI 2 Claude 2 PetalBot 2 Meta AI 1
crawler 50 crawler_json 5
DEV INTEL Tools & Severity
🟠 High ⚙ Fix effort: Medium
⚡ Quick Fix
Choose the right hash for the use case: SHA-256 for data integrity checksums, HMAC-SHA-256 for authentication tags, Argon2id for passwords — never MD5 or SHA1 for any security use
📦 Applies To
PHP 5.1+ web cli queue-worker
🔗 Prerequisites
🔍 Detection Hints
md5() sha1() for security; hash without HMAC for authentication; SHA-256 for passwords instead of Argon2id
Auto-detectable: ✓ Yes semgrep psalm phpstan
⚠ Related Problems
🤖 AI Agent
Confidence: Medium False Positives: Medium ✓ Auto-fixable Fix: Low Context: Line
CWE-327 CWE-328


✓ schema.org compliant