Cryptographic Hashing for Developers: MD5, SHA-256, and HMAC Explained

1 6 110
calendar_todayschedule4 min read

Cryptographic hashes appear in password storage, file verification, API authentication, digital signatures, and blockchains. Here's how they work and which one to use for each purpose.

What is a cryptographic hash?

A hash function takes input of any length and produces a fixed-length output. The key properties:

  • Deterministic: The same input always produces the same hash.
  • One-way: You cannot reverse a hash to get the original input.
  • Avalanche effect: A small change in input produces a completely different hash.
  • Collision-resistant: It should be computationally infeasible to find two different inputs that produce the same hash.

A hash generator lets you compute MD5, SHA-1, SHA-256, and SHA-512 from text or files instantly in the browser.

MD5 (128-bit / 32 hex chars)

``

MD5("hello") = 5d41402abc4b2a76b9719d911017c592

`

Status: Cryptographically broken. MD5 is vulnerable to collision attacks — it's possible to find two different inputs with the same MD5 hash in milliseconds with modern hardware.

Use it for: Non-security checksums (detecting accidental corruption), legacy system compatibility, cache keys, non-sensitive data fingerprinting.

Do NOT use it for: Password hashing, digital signatures, security-critical file verification.

SHA-1 (160-bit / 40 hex chars)

<code> <p>SHA-1("hello") = aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d</p> </code>

Status: Cryptographically weak. SHA-1 collision attacks have been practically demonstrated (SHAttered, 2017). Major certificate authorities and Git (for new repos) have moved away from SHA-1.

Use it for: Legacy compatibility only. Old Git commits still use SHA-1. Avoid for new systems.

SHA-256 (256-bit / 64 hex chars)

<code> <p>SHA-256("hello") = 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824</p> </code>

Status: Current standard. No known practical attacks. Part of the SHA-2 family (also includes SHA-384, SHA-512).

Use it for: File integrity verification, digital signatures, API request signing, blockchain transactions, HMAC keys, everywhere SHA-1 was used.

SHA-512 (512-bit / 128 hex chars)

<code> <p>SHA-512("hello") = 9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043...</p> </code>

Status: Even more resistant than SHA-256. The output is longer (better for collision resistance) but computationally slightly more expensive.

Use it for: When SHA-256 isn't strong enough (extremely high-security scenarios, long-term archival integrity). The extra strength is rarely necessary for most applications.

HMAC: Keyed Hashing

HMAC (Hash-based Message Authentication Code) combines a secret key with the hash to authenticate both data integrity and identity.

<code> <p>HMAC-SHA256(key, message) = a unique hash per key+message pair</p> </code>

Uses: API authentication (signing requests), JWT validation (HS256), webhook verification, session tokens.

How it works:
<code> <p>HMAC(K, m) = H((K' XOR opad) || H((K' XOR ipad) || m))</p> </code>

In practice, you use a library:

<code>javascript <p>// Node.js</p> <p>const crypto = require('crypto');</p> <p>const hmac = crypto.createHmac('sha256', secretKey);</p> <p>hmac.update(message);</p> <p>const signature = hmac.digest('hex');</p> </code>

<code>python <p>import hmac, hashlib</p> <p>signature = hmac.new(secret_key.encode(), message.encode(), hashlib.sha256).hexdigest()</p> </code>

Password hashing: don't use SHA

SHA algorithms are fast — by design. This makes them terrible for password hashing, because an attacker can compute billions of SHA hashes per second on a GPU.

Use purpose-built password hashing algorithms:

  • bcrypt: Adaptive cost factor, resistant to GPU attacks. Standard for most web apps.
  • Argon2: Winner of the Password Hashing Competition (2015). Three variants: Argon2i (side-channel resistant), Argon2d (GPU resistant), Argon2id (both). Recommended for new systems.
  • scrypt: Memory-hard algorithm. Widely used (Litecoin, OpenSSL).

`python
Python: bcrypt
import bcrypt


hashed = bcrypt.hashpw(password.encode(), bcrypt.gensalt(rounds=12))


is_valid = bcrypt.checkpw(password.encode(), hashed)

Python: Argon2

from argon2 import PasswordHasher

ph = PasswordHasher(time_cost=3, memory_cost=65536, parallelism=1)

hashed = ph.hash(password)

is_valid = ph.verify(hashed, password)

`

<code>javascript <p>// Node.js: bcrypt</p> <p>const bcrypt = require('bcrypt');</p> <p>const hash = await bcrypt.hash(password, 12);</p> <p>const valid = await bcrypt.compare(password, hash);</p> </code>

File verification

Verifying a downloaded file is intact:

`bash
Linux/macOS
sha256sum downloaded-file.iso # Compute hash


echo "expected_hash downloaded-file.iso" | sha256sum --check # Verify

macOS (alternative)

shasum -a 256 downloaded-file.iso

Windows (PowerShell)

Get-FileHash downloaded-file.iso -Algorithm SHA256

`

In Python:

`python
import hashlib, sys

def file_hash(path, algorithm='sha256'):

h = hashlib.new(algorithm)

with open(path, 'rb') as f:

while chunk := f.read(65536):

h.update(chunk)

return h.hexdigest()

print(file_hash('large-file.iso'))

``

Choosing the right hash function

| Use case | Recommended |

|----------|-------------|

| File integrity check (non-security) | MD5 or SHA-256 |

| File integrity check (security) | SHA-256 |

| Digital signatures | SHA-256 or SHA-512 |

| API request signing | HMAC-SHA256 |

| JWT tokens | HMAC-SHA256 (HS256) or RSA-SHA256 (RS256) |

| Password storage | Argon2id or bcrypt |

| Blockchain | SHA-256 (Bitcoin), Keccak-256 (Ethereum) |

| UUID generation | Not a hash — use crypto.randomUUID() |

Never use MD5 or SHA-1 for anything security-sensitive. SHA-256 covers most needs; add HMAC when you need authentication alongside integrity.

Originally published at https://snappytools.app/hash-generator/

🔥 Join developers growing publicly
Share your knowledge, build in public, and grow your developer presence with a global community.

More Posts

Comparison: Universal Import vs. Plaid/Yodlee

Pocket Portfolio - Mar 12

I’m a Senior Dev and I’ve Forgotten How to Think Without a Prompt

Karol Modelskiverified - Mar 19

What Is SARIF and How Does It Help Security Tools Work Together?

Ganesh Kumar - Jul 4

The Interface of Uncertainty: Designing Human-in-the-Loop

Pocket Portfolio - Mar 10

TypeScript Complexity Has Finally Reached the Point of Total Absurdity

Karol Modelskiverified - Apr 23
chevron_left
2.4k Points117 Badges
101Posts
0Comments
SnappyTools builds free, fast, browser-based tools for developers, writers, and designers. No signup... Show more

Related Jobs

View all jobs →

Commenters (This Week)

1 comment
1 comment
1 comment

Contribute meaningful comments to climb the leaderboard and earn badges!