Generate MD5, SHA-1, SHA-256, SHA-512, and bcrypt hashes. Runs entirely in your browser — nothing is sent to a server.
Each algorithm is designed for a different purpose. Using the wrong one is one of the most common security mistakes in web development — particularly storing passwords with SHA-256.
| Algorithm | Output | Speed | Security | Use for | Never use for |
|---|---|---|---|---|---|
| MD5 | 128-bit / 32 hex chars | Very fast | Broken | Non-security checksums, cache keys, deduplication | Passwords, signatures, certificates |
| SHA-1 | 160-bit / 40 hex chars | Fast | Deprecated | Legacy system compatibility only | Any new application |
| SHA-256 | 256-bit / 64 hex chars | Fast | Strong | File integrity, API signatures, JWT, TLS certificates, HMAC | Password storage (too fast — see below) |
| SHA-512 | 512-bit / 128 hex chars | Fast | Strong | High-security data integrity, longer hash output required | Password storage |
| bcrypt | 60-char string (includes salt) | Deliberately slow | Recommended for passwords | Password hashing only | File checksums, data integrity (use SHA-256 instead) |
SHA-256 is a strong, collision-resistant algorithm — but it was designed to be fast. That speed is exactly the problem for passwords.
A modern consumer GPU can compute roughly 8 billion SHA-256 hashes per second. An attacker who steals your password database can test every word in a dictionary, every common password, and millions of variations in under a minute — even if you add a salt.
bcrypt is deliberately slow. At cost factor 12, a single bcrypt hash takes roughly 400ms on commodity hardware. That rate-limits an attacker to approximately 2–3 guesses per second per machine, making offline brute-force attacks economically impractical for strong passwords.
The OWASP Password Storage Cheat Sheet recommends bcrypt, scrypt, or Argon2id for password hashing. All three share the same property: adjustable slowness that scales with hardware improvements.
Each increment to the cost factor doubles the computation time. The goal is to make login feel instant to a human (~400ms is imperceptible) while making offline attacks expensive. Increase the cost factor as hardware gets faster — benchmark your production server and pick the highest value that keeps login under 1 second.
| Cost factor | Approx. time | Recommendation |
|---|---|---|
| 4 | ~1ms | Unit tests only — never production |
| 10 | ~100ms | Low-traffic apps, acceptable trade-off |
| 12default | ~400ms | Default — recommended for most applications |
| 13 | ~800ms | Higher security, noticeable on high-traffic login endpoints |
| 14 | ~1.6s | High-security systems — test your server capacity first |
A hash function takes any input — a single character, a 10GB file, a password — and produces a fixed-length output called a digest. Three properties define a cryptographic hash function:
Hashing is not encryption. Encryption is reversible given a key. Hashing is intentionally irreversible. Use hashing when you need to verify data without storing the original; use encryption when you need the original data back.
Three of the four mistakes below can lead directly to a data breach. The fourth causes silent bugs that are hard to diagnose.
// Storing user passwords — DO NOT do this const hash = await crypto.subtle.digest( "SHA-256", new TextEncoder().encode(password) )
// Correct: use bcrypt with cost ≥ 12 import bcrypt from "bcryptjs" const hash = await bcrypt.hash(password, 12)
Modern GPUs compute roughly 8 billion SHA-256 hashes per second. An attacker with a leaked database can brute-force common passwords in seconds — even with a salt. bcrypt is deliberately slow: at cost 12, a single hash takes ~400ms on commodity hardware, limiting an attacker to roughly 2–3 attempts per second per machine.
// Will fail if one hash is uppercase and the other is lowercase
if (storedHash === incomingHash) { ... }// Normalise both to the same case before comparing
if (storedHash.toLowerCase() === incomingHash.toLowerCase()) { ... }SHA hashes are hexadecimal strings. Some systems output uppercase (A1B2C3), others lowercase (a1b2c3). They represent the same value. Always normalise to the same case — or use a constant-time comparison function to avoid timing attacks.
// bcrypt truncates input at 72 bytes const fileHash = await bcrypt.hash(fileContents, 12)
// Use SHA-256 for files — fast and collision-resistant const hash = await crypto.subtle.digest( "SHA-256", fileBuffer )
bcrypt silently truncates input at 72 bytes. Two different files that share the same first 72 bytes will produce the same bcrypt hash. bcrypt is designed for short secrets (passwords), not arbitrary data. Use SHA-256 or SHA-512 for file integrity.
// This will always be false — bcrypt includes a random salt
bcrypt.hash("password", 12) === bcrypt.hash("password", 12)// Always use compare — never hash again and compare const match = await bcrypt.compare(plaintext, storedHash)
Every bcrypt call generates a new random salt, producing a different 60-character hash even for identical input. To verify a password, use bcrypt.compare(plaintext, storedHash) — it extracts the salt from the stored hash, recomputes, and compares internally.
Encryption is reversible — given the key, you can decrypt ciphertext back to plaintext. Hashing is a one-way function: it produces a fixed-length digest from any input, and there is no algorithm to recover the original input from the hash alone. You use encryption when you need the original data back (e.g. storing an API key you will later use). You use hashing when you only need to verify data (e.g. passwords, file integrity).
Use bcrypt (cost factor 12 or higher), scrypt, or Argon2id. These are specifically designed for password hashing — they are slow by design, include a salt automatically, and resist GPU and ASIC brute-force attacks. The OWASP Password Storage Cheat Sheet recommends all three. Never use MD5, SHA-1, SHA-256, or SHA-512 for password storage — they are too fast.
SHA-256 is the standard choice for file integrity verification. It is fast, collision-resistant, and widely supported. SHA-512 is acceptable for higher security margins. Avoid MD5 and SHA-1 for security-sensitive integrity checks — both have known collision vulnerabilities where two different inputs can produce the same hash.
bcrypt automatically generates a random 128-bit salt for each call and embeds it into the output hash string. This is intentional — it means two users with the same password have different stored hashes, preventing rainbow table attacks. To verify a password, always use bcrypt.compare(plaintext, storedHash). Never hash the password again and compare the two hashes.
The cost factor (also called rounds or work factor) controls how slow bcrypt is. Each increment doubles the computation time. Cost 12 takes roughly 400ms and is the recommended default for most web applications. Increase it as hardware gets faster — the goal is to keep login time under 1 second while making offline brute-force attacks computationally expensive.
MD5 is safe for non-security uses: cache keys, ETags, deduplication fingerprints, and non-cryptographic checksums. It is broken for any security-sensitive use. Researchers demonstrated MD5 collision attacks in 2004, and tools to find collisions are publicly available. Never use MD5 for password hashing, digital signatures, or verifying software authenticity.
No. All hashing runs in your browser. SHA-1, SHA-256, and SHA-512 use the browser's built-in Web Crypto API (window.crypto.subtle), which never leaves the JavaScript sandbox. MD5 runs via a pure-JavaScript implementation. bcrypt runs via the bcryptjs library, also entirely in-browser. You can disconnect from the internet after loading the page and the tool will continue to work.
SHA-256 is a general-purpose hash function optimised to be fast. A modern GPU can compute roughly 8 billion SHA-256 hashes per second. An attacker who steals your password database can test every common password and variation in seconds. bcrypt is orders of magnitude slower by design — at cost 12, a single bcrypt hash takes ~400ms, limiting an attacker to roughly 2–3 guesses per second per machine regardless of hardware.