DEV Community

ze he
ze he

Posted on • Originally published at aiforeverthing.com

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

MD5 vs SHA1 vs SHA256: Which Hash Should You Use?

Hash functions are everywhere in software — file checksums, JWT signatures, API authentication, password storage. But picking the wrong one can be a serious security mistake.

Quick tool: Hash Generator Online — generate MD5, SHA1, SHA256, SHA512 in your browser (free, private).


TL;DR — The Decision Table

Use case Algorithm Notes
Password storage bcrypt / Argon2 Never use MD5/SHA
Digital signatures SHA-256 NIST approved
File integrity SHA-256 or MD5 MD5 ok for non-security uses
JWT (HS256) SHA-256 Standard choice
Git commits SHA-1 (→ SHA-256) Being migrated
TLS certificates SHA-256 SHA-1 certs rejected
HMAC SHA-256 or SHA-512 Both secure

Understanding Hash Functions

A cryptographic 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
Enter fullscreen mode Exit fullscreen mode

Key properties:

  • Deterministic: same input always → same output
  • One-way: you can't reverse a hash to get the input
  • Avalanche effect: changing one bit completely changes the output
  • Collision resistant: it should be infeasible to find two inputs with the same hash

MD5 — Fast but Broken

Status: Cryptographically broken. Use only for non-security checksums.

MD5 produces a 128-bit (32 hex char) hash. It was widely used through the 1990s but has been thoroughly broken:

  • 2004: Collision attacks demonstrated
  • 2008: Rogue CA certificates created using MD5 collisions
  • 2012: Flame malware forged Windows Update signatures using MD5
// Node.js
const crypto = require('crypto');
const hash = crypto.createHash('md5').update('Hello').digest('hex');
// 8b1a9953c4611296a827abf8c47804d7
Enter fullscreen mode Exit fullscreen mode

Safe uses for MD5:

  • Non-security file deduplication
  • Caching keys (where collisions don't matter)
  • Legacy system compatibility

Unsafe uses:

  • Password hashing (use bcrypt/Argon2)
  • Digital signatures
  • SSL/TLS certificates
  • Any security-critical context

SHA-1 — Deprecated, Being Phased Out

Status: Deprecated. Practical collision attacks demonstrated.

SHA-1 produces a 160-bit (40 hex char) hash. The "SHAttered" attack in 2017 demonstrated the first real-world SHA-1 collision:

# Two different PDFs with the same SHA-1 hash
sha1sum shattered-1.pdf shattered-2.pdf
# 38762cf7f55934b34d179ae6a4c80cadccbb7f0a  shattered-1.pdf
# 38762cf7f55934b34d179ae6a4c80cadccbb7f0a  shattered-2.pdf
Enter fullscreen mode Exit fullscreen mode

Git still uses SHA-1 for commit IDs (though SHA-256 migration is underway). Browsers reject TLS certificates signed with SHA-1.


SHA-256 — The Current Standard

Status: Secure. Recommended for new applications.

Part of the SHA-2 family, SHA-256 produces a 256-bit (64 hex char) hash. Used in:

  • Bitcoin blockchain
  • TLS 1.3
  • JWT (HS256, RS256, ES256)
  • Code signing certificates
  • Password managers
// Node.js
const crypto = require('crypto');
const hash = crypto.createHash('sha256').update('Hello').digest('hex');
// 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);
Enter fullscreen mode Exit fullscreen mode
import hashlib
hash = hashlib.sha256(b'Hello').hexdigest()
print(hash)
Enter fullscreen mode Exit fullscreen mode

HMAC — For Authentication

HMAC (Hash-based Message Authentication Code) uses 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)  # Use this to verify the message wasn't tampered with
Enter fullscreen mode Exit fullscreen mode

Used in:

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

The Password Hashing Trap

This is the most common mistake:

# WRONG — never do this
import hashlib
password_hash = hashlib.sha256(password.encode()).hexdigest()

# RIGHT — use bcrypt
import bcrypt
hashed = bcrypt.hashpw(password.encode(), bcrypt.gensalt())
Enter fullscreen mode Exit fullscreen mode

Why SHA-256 fails for passwords:

  1. Too fast — attackers can try billions per second
  2. No salt by default — rainbow tables work
  3. Deterministic — same password = same hash, leaks duplicates

bcrypt, scrypt, and Argon2 are designed to be:

  • Slow (configurable cost)
  • Salted automatically
  • Memory-intensive (Argon2/scrypt)

Quick Reference: Hashing in Popular Languages

JavaScript (Node.js):

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

Python:

import hashlib, hmac
hashlib.sha256(b'text').hexdigest()
hmac.new(b'key', b'text', hashlib.sha256).hexdigest()
Enter fullscreen mode Exit fullscreen mode

Go:

import "crypto/sha256"
h := sha256.Sum256([]byte("text"))
fmt.Printf("%x\n", h)
Enter fullscreen mode Exit fullscreen mode

Shell:

echo -n "text" | sha256sum
echo -n "text" | md5sum
Enter fullscreen mode Exit fullscreen mode

Online Hash Generator

Need to quickly hash a string or verify a checksum? Use the DevKits Hash Generator:

  • MD5, SHA-1, SHA-256, SHA-384, SHA-512
  • HMAC support with custom secret key
  • File hashing (drag & drop)
  • 100% browser-based — nothing sent to a server
  • Free, no signup

Or use the API for programmatic access:

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

Summary

  • MD5: Fast, broken, use only for non-security checksums
  • SHA-1: Deprecated, avoid for new code
  • SHA-256: Current standard, use for everything new
  • SHA-512: Max security, often faster on 64-bit
  • bcrypt/Argon2: For passwords — always, no exceptions
  • HMAC-SHA256: For message authentication and JWT

Top comments (0)