MD5 vs SHA1 vs SHA256: Which Hash Should You Use? (With Live Examples)

Published: (March 19, 2026 at 03:17 PM EDT)
5 min read
Source: Dev.to

Source: Dev.to

Choosing the right algorithm

Use caseRecommended algorithm(s)Notes
Password storagebcrypt / Argon2Never use MD5/SHA‑1/SHA‑256 directly
Digital signaturesSHA‑256NIST‑approved
File integritySHA‑256 (or MD5)MD5 ok only for non‑security uses
JWT (HS256)SHA‑256Standard choice
Git commitsSHA‑1 → SHA‑256Migration in progress
TLS certificatesSHA‑256SHA‑1 certificates are rejected
HMACSHA‑256 or SHA‑512Both are secure

How a cryptographic hash works

A hash function takes arbitrary input and produces a fixed‑length output.

import hashlib

text = "Hello, World!"

md5    = hashlib.md5(text.encode()).hexdigest()     # 32 hex chars
sha1   = hashlib.sha1(text.encode()).hexdigest()    # 40 hex chars
sha256 = hashlib.sha256(text.encode()).hexdigest()  # 64 hex chars
sha512 = hashlib.sha512(text.encode()).hexdigest()  # 128 hex chars

print(sha256)
# 315f5bdb76d078c43b8ac0064e4a0164612b1fce77c869345bfc94c75894edd3

Key properties

  • Deterministic – same input always yields the same output.
  • One‑way – infeasible to reverse the hash.
  • Avalanche effect – a single‑bit change completely changes the output.
  • Collision resistant – hard to find two distinct inputs with the same hash.

MD5

Produces a 128‑bit (32‑hex‑char) hash.

  • Status: Cryptographically broken. Use only for non‑security checksums.
  • Historical attacks:
    • 2004 – collision attacks demonstrated.
    • 2008 – rogue CA certificates created using MD5 collisions.
    • 2012 – Flame malware forged Windows Update signatures.
// Node.js
const crypto = require('crypto');
const hash = crypto.createHash('md5').update('Hello').digest('hex');
console.log(hash); // 8b1a9953c4611296a827abf8c47804d7

Safe uses

  • Non‑security file deduplication.
  • Caching keys where collisions are acceptable.
  • Legacy system compatibility.

Unsafe uses

  • Password hashing.
  • Digital signatures.
  • SSL/TLS certificates.
  • Any security‑critical context.

SHA‑1

Produces a 160‑bit (40‑hex‑char) hash.

  • Status: Deprecated for new code; collisions are feasible.
  • Notable attack: 2017 “SHAttered” collision demonstrated two different PDFs with identical SHA‑1 hashes.
# Two different PDFs with the same SHA‑1 hash
sha1sum shattered-1.pdf shattered-2.pdf
# 38762cf7f55934b34d179ae6a4c80cadccbb7f0a  shattered-1.pdf
# 38762cf7f55934b34d179ae6a4c80cadccbb7f0a  shattered-2.pdf
  • Git still uses SHA‑1 for commit IDs (migration to SHA‑256 is underway).
  • Browsers reject TLS certificates signed with SHA‑1.

Recommendation: Avoid SHA‑1 in new applications; migrate existing uses where possible.

SHA‑256 (part of the SHA‑2 family)

Produces a 256‑bit (64‑hex‑char) hash.

  • Status: Current standard; widely trusted.
  • Common uses:
    • Bitcoin blockchain.
    • TLS 1.3.
    • JWT signatures (HS256, RS256, ES256).
    • Code‑signing certificates.
    • Password managers.
// Node.js
const crypto = require('crypto');
const hash = crypto.createHash('sha256').update('Hello').digest('hex');
console.log(hash); // 185f8db32921bd46d35cc3c66b9a7b8f3a2bc37f9f0e87c
// Browser (Web Crypto API)
async function sha256(text) {
  const data = new TextEncoder().encode(text);
  const buf = await crypto.subtle.digest('SHA-256', data);
  return Array.from(new Uint8Array(buf))
    .map(b => b.toString(16).padStart(2, '0'))
    .join('');
}
sha256('Hello').then(console.log);
import hashlib
print(hashlib.sha256(b'Hello').hexdigest())

HMAC (Hash‑based Message Authentication Code)

Combines a secret key with a hash function to authenticate messages.

import hmac, hashlib

secret = b'my-secret-key'
message = b'user_id=123&amount=50'

sig = hmac.new(secret, message, hashlib.sha256).hexdigest()
print(sig)  # Verify that the message wasn't tampered with

Typical uses

  • JWT signatures (HS256 = HMAC‑SHA256).
  • Webhook payload verification (GitHub, Stripe).
  • API request signing (AWS Signature V4).

Password hashing: why plain SHA‑256 is wrong

# WRONG — never do this
import hashlib
password_hash = hashlib.sha256(password.encode()).hexdigest()
  • Too fast – attackers can try billions of guesses per second.
  • No salt – vulnerable to rainbow‑table attacks.
  • Deterministic – identical passwords produce identical hashes, leaking duplicates.

Correct approach

# RIGHT — use bcrypt (or Argon2/scrypt)
import bcrypt
hashed = bcrypt.hashpw(password.encode(), bcrypt.gensalt())

Properties of proper password hashers

  • Slow – configurable cost factor.
  • Salted – unique per password.
  • Memory‑hard – Argon2 and scrypt resist GPU/ASIC attacks.

Quick language snippets

Node.js (crypto module)

const { createHash, createHmac } = require('crypto');
createHash('sha256').update('text').digest('hex');
createHmac('sha256', 'key').update('text').digest('hex');

Python

import hashlib, hmac
hashlib.sha256(b'text').hexdigest()
hmac.new(b'key', b'text', hashlib.sha256).hexdigest()

Go

import "crypto/sha256"
import "fmt"

func main() {
    h := sha256.Sum256([]byte("text"))
    fmt.Printf("%x\n", h)
}

Shell

echo -n "text" | sha256sum
echo -n "text" | md5sum

API example: programmatic hashing

curl -X POST https://api.aiforeverthing.com/api/hash/generate \
  -H "Content-Type: application/json" \
  -d '{"text": "hello world", "algorithm": "sha256"}'

Summary cheat‑sheet

AlgorithmTypical use caseSecurity stance
MD5Non‑security checksums, legacy deduplicationFast, broken – use only for non‑security
SHA‑1Legacy systems (e.g., old Git repos)Deprecated – avoid in new code
SHA‑256General purpose hashing, signatures, JWT, TLSCurrent standard – default choice
SHA‑512Maximum security, often faster on 64‑bit CPUsStrong – use when extra margin is needed
bcrypt / Argon2 / scryptPassword storageAlways use a dedicated password hasher
HMAC‑SHA256 (or SHA‑512)Message authentication, API signing, JWTSecure for authenticated contexts

Choose the algorithm that matches the security requirements of your application; never use a broken hash (MD5, SHA‑1) for anything security‑critical.

0 views
Back to Blog

Related posts

Read more »