BuildQuill
Comparison Guides11 min read

MD5 vs SHA-1 vs SHA-256 vs SHA-512: Which Hash Should You Use?

A clear comparison of common hash algorithms: speed, collision resistance, file checksums, password storage, signatures, and practical security choices.

MD5 vs SHA-1 vs SHA-256 vs SHA-512: Which Hash Should You Use?

Hash algorithms are easy to use and easy to misuse. You paste text into a hash tool, get a fixed-length string back, and it feels official. But not every hash is appropriate for every job. MD5, SHA-1, SHA-256, and SHA-512 all create fingerprints of data, yet they sit in very different places on the security timeline.

The short version: do not use MD5 or SHA-1 for security. Use SHA-256 or SHA-512 for modern checksums, signatures, and integrity checks. For passwords, do not use any plain fast hash by itself; use a password hashing algorithm such as Argon2, bcrypt, scrypt, or PBKDF2 with proper settings.

That is the short version. The longer version matters because real projects are full of awkward cases: old APIs, file checksums, cache keys, duplicate detection, signed webhooks, migration scripts, and legacy database columns that refuse to disappear politely.

This guide compares the common hash families in practical terms: speed, output size, collision resistance, security status, and what you should actually choose.

What a Hash Function Does

A cryptographic hash function takes input of any size and produces a fixed-size output.

Example:

Text
hello

SHA-256:

Text
2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824

Three properties make cryptographic hashes useful.

First, the same input should always produce the same output. This makes hashes useful for file checksums and comparisons.

Second, a tiny input change should completely change the output. hello and Hello should not produce similar-looking hashes.

Third, it should be computationally hard to find two different inputs with the same hash. That is collision resistance, and it is where old algorithms like MD5 and SHA-1 fail for security-sensitive use.

Hashing is not encryption. You cannot decrypt a hash. A hash is a fingerprint, not a locked box. If someone says "we encrypted the password with MD5", that sentence is doing two jobs badly: MD5 is a hash, and plain MD5 is not acceptable password storage.

MD5: Fast, Familiar, Broken for Security

MD5 produces a 128-bit hash, commonly shown as 32 hex characters.

Text
5d41402abc4b2a76b9719d911017c592

MD5 is old, fast, and everywhere in legacy systems. It is also cryptographically broken. Practical collision attacks exist, which means attackers can create different inputs with the same MD5 hash under realistic conditions.

MD5 is acceptable for:

  • Non-security duplicate detection in trusted data.
  • Legacy compatibility where the protocol requires it.
  • Quick internal checks where collision attacks do not matter.
  • Identifying files in old systems that already use MD5.

MD5 is not acceptable for:

  • Password storage.
  • Digital signatures.
  • Certificate security.
  • Tamper-proof file verification from untrusted sources.
  • Any new security-sensitive design.

MD5's speed is part of the problem. Fast hashes are useful for checksums, but terrible for passwords. An attacker can try billions of MD5 guesses quickly with modern hardware. Even salted MD5 is not enough for password storage today.

The practical rule: if MD5 appears in a new design document, stop and ask why. There are rare compatibility reasons, but there are almost no good fresh-design reasons.

Our MD5 Hash Generator can help when you need to compare a legacy value, but the label "legacy" should be loud in your head.

SHA-1: Also Broken for Security

SHA-1 produces a 160-bit hash, usually shown as 40 hex characters.

Text
aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d

For years, SHA-1 was the safer replacement for MD5. That era is over. SHA-1 collision attacks are practical enough that major browsers, certificate authorities, Git, and security teams have spent years moving away from it.

SHA-1 is acceptable for:

  • Legacy identifiers where security is not the point.
  • Backward compatibility with old systems.
  • Reading historical data.
  • Non-adversarial internal deduplication, if migration is not worth it.

SHA-1 is not acceptable for:

  • New digital signatures.
  • Certificates.
  • Password storage.
  • Tamper-resistant file verification.
  • Any new security-sensitive protocol.

SHA-1 has a slightly better reputation than MD5 in some older teams because it failed later, but for practical decision-making, treat both as retired for security. If someone can choose the input and benefit from a collision, SHA-1 is the wrong tool.

There are still ecosystems where SHA-1 appears as an identifier. Git historically used SHA-1 object IDs, for example, while adding protections and moving toward stronger options. That does not mean you should casually use SHA-1 for your own security feature. Context matters.

SHA-256: The Modern Default

SHA-256 is part of the SHA-2 family and produces a 256-bit hash, shown as 64 hex characters.

Text
2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824

For most modern applications, SHA-256 is the default answer. It is widely supported, strong, familiar to security reviewers, and efficient enough for ordinary integrity checks.

SHA-256 is good for:

  • File checksums.
  • API signatures and HMACs.
  • Integrity verification.
  • Content addressing.
  • Tamper detection.
  • General-purpose cryptographic hashing.

SHA-256 is also the algorithm many people recognize from package downloads and release checksums. If a website publishes a SHA-256 checksum for a file, you can hash your downloaded file and compare the result. If the hashes match, the file is very likely identical to the published one.

One important distinction: use HMAC-SHA-256 for message authentication with a secret key. Do not invent your own pattern like sha256(secret + message) unless you are deliberately trying to make future-you sigh. HMAC exists because combining secrets and hashes correctly has details.

SHA-256 is not a password hashing algorithm by itself. It is too fast. For passwords, use a slow, salted password hashing function. SHA-256 can appear inside some password-hashing constructions, but plain sha256(password) is not enough.

Our SHA-256 Hash Generator is a good everyday choice when you need a modern digest for text or file-like values.

SHA-512: Stronger Output, Different Performance Tradeoffs

SHA-512 is also part of SHA-2. It produces a 512-bit hash, shown as 128 hex characters.

Text
9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca7
23c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043

SHA-512 looks twice as strong because the output is twice as long. In practical terms, SHA-256 is already strong enough for normal collision resistance needs. SHA-512 can still be a great choice, especially on 64-bit systems where it may perform very well.

SHA-512 is good for:

  • High-security integrity checks.
  • Systems already standardized on SHA-512.
  • Environments where 64-bit performance is favorable.
  • Cases where a longer digest is acceptable.

The downside is output length. A 128-character hex string is bulky in URLs, database columns, logs, and user-facing displays. That does not make it bad. It just means you should have a reason.

There are also SHA-512 variants such as SHA-512/256, which use the SHA-512 internal design but output 256 bits. Those can be excellent, but plain SHA-256 is more widely recognized by general developers and tooling.

Use SHA-512 when your ecosystem expects it, when performance testing favors it, or when your security requirements specifically call for it. Use SHA-256 when you simply need a strong modern default.

Head-to-Head Summary

Algorithm Output Bits Hex Length Security Status Use Today
MD5 128 32 Broken for collisions Legacy/non-security only
SHA-1 160 40 Broken for collisions Legacy/non-security only
SHA-256 256 64 Strong Modern default
SHA-512 512 128 Strong Strong option, longer output

The table makes the recommendation fairly obvious. MD5 and SHA-1 are historical. SHA-256 and SHA-512 are current. But there are still decisions inside that recommendation, especially around passwords and signatures.

Checksums vs Security Checks

People often say "checksum" for any hash, but there is a difference between accidental corruption and malicious tampering.

If you are checking whether a file got corrupted during transfer, a simple checksum may be enough. Even older hashes can detect random corruption well. If a bit flips by accident, MD5 will almost certainly change.

If you are checking whether an attacker changed a file, collision resistance matters. An attacker may be able to craft a malicious file with the same weak hash. That is where MD5 and SHA-1 are not acceptable.

For public downloads, use SHA-256 or better. For internal non-adversarial duplicate detection, you may still see MD5 because it is fast and compact. Just do not confuse "works for accidental differences" with "safe against attackers."

Hashes for Passwords

This is the section that saves real pain.

Do not store passwords as MD5, SHA-1, SHA-256, or SHA-512 hashes by themselves. Not even with a clever-looking double hash. Not even if you add a salt and feel responsible. General-purpose hashes are designed to be fast. Password hashing should be slow and resistant to specialized cracking hardware.

Use a password hashing function:

  • Argon2id when available.
  • bcrypt when you need broad support and mature defaults.
  • scrypt when memory hardness is useful and supported.
  • PBKDF2 when compliance or platform constraints require it.

A proper password hash includes a unique salt and work parameters. The salt prevents identical passwords from having identical hashes and makes precomputed rainbow tables less useful. The work factor slows down guessing.

Hash tools are still useful for learning and for non-password tasks. Just keep password storage in its own mental box.

Hashes for API Signatures

When a webhook provider signs a request, you usually see HMAC with SHA-256 or SHA-512. HMAC means a secret key is involved, and the receiver can verify that the message came from someone with the same secret and was not changed.

Example concept:

Text
signature = HMAC_SHA256(secret, request_body)

This is different from:

Text
signature = SHA256(secret + request_body)

The second pattern is a homemade construction and can be vulnerable depending on the hash and format. Use HMAC libraries. They are boring in the best way.

Also compare signatures using constant-time comparison functions when available. Tiny timing differences can leak information in high-risk contexts.

Hashes for Cache Keys and Deduplication

Not every hash use is high-security. Sometimes you need a stable ID for a large object, a cache key for a response, or a way to detect duplicate content.

For cache keys, SHA-256 is safe and simple. For internal speed-sensitive deduplication where inputs are trusted, non-cryptographic hashes may be faster, but they belong to a different category. If collision damage would be serious, use a cryptographic hash.

For file deduplication, think about the cost of a false match. If a collision would only cause a harmless extra comparison, fine. If a collision could delete the wrong file, verify size and maybe compare bytes after matching hashes.

Migration From MD5 or SHA-1

Legacy systems rarely let you switch everything in one afternoon. A practical migration usually has stages.

First, identify what the hash protects. Is it a password, file checksum, cache key, signature, or database identifier? The risk depends on the job.

Second, add a new field or version marker if needed. Store sha256_hash next to md5_hash, or add an algorithm prefix like:

Text
sha256:2cf24dba5fb0a30e26e83b2ac5b9e29e...

Third, verify both during transition if clients still send old values. Fourth, stop generating weak hashes. Fifth, remove old verification when compatibility allows.

For passwords, migration often happens on login: verify the old hash once, then rehash the password with the modern password hashing algorithm and store the new result.

Output Formats: Hex, Base64, and Raw Bytes

Hash output is bytes. The string you usually see is an encoding of those bytes. Most developer tools show hashes as hex because hex is predictable and easy to compare. Every byte becomes two characters, so SHA-256 becomes 64 hex characters and SHA-512 becomes 128.

Base64 is also common in APIs because it is shorter than hex. A raw 32-byte SHA-256 digest is 44 characters in padded Base64, compared with 64 characters in hex. That can matter in headers, tokens, and compact database fields. The tradeoff is readability. Hex is easier to compare by eye, while Base64 is easier to fit into a smaller text field.

Raw bytes are best inside code or binary storage. If a library returns a byte array, keep it as bytes until you actually need to display or transmit it. Converting back and forth between hex strings and bytes is a common source of subtle bugs, especially when one system expects lowercase hex and another expects Base64URL.

When two hashes do not match, confirm the representation before blaming the algorithm. Check whether both sides hashed the same exact bytes, used the same character encoding, normalized line endings the same way, and displayed the digest in the same format. A missing newline at the end of a file can change the hash completely. So can hashing the string "hello" in one system and the UTF-16 representation of hello in another.

This is why good checksum documentation says more than "use SHA-256." It should say what is hashed, how text is encoded, whether line endings matter, and how the digest is represented. Boring details, yes, but boring details are where hash bugs like to hide.

Salts, Peppers, and Why They Do Not Save Fast Hashes

You will often hear that passwords should be "salted." That is true, but it is incomplete. A salt is a unique random value stored with each password hash. It prevents two users with the same password from having the same stored hash and blocks large precomputed lookup tables.

A pepper is a separate secret value stored outside the database, often in application configuration or a secrets manager. It can add protection if the database leaks but the application secret does not.

Both are useful concepts, but neither turns MD5 or plain SHA-256 into a modern password hashing system. Attackers can still make guesses extremely quickly. Proper password hashing functions include salts and are intentionally expensive to compute. Some are also memory-hard, which makes large-scale cracking more costly.

So the practical rule is not "salt your SHA-256 password hashes." The practical rule is "use a password hashing library that handles salts and work factors correctly." Security work gets better when we stop hand-assembling parts that already have battle-tested implementations.

The Decision Framework

Ask these questions.

1. Is this for passwords? Use Argon2id, bcrypt, scrypt, or PBKDF2. Not plain MD5, SHA-1, SHA-256, or SHA-512.

2. Is this a new security-sensitive feature? Use SHA-256 or SHA-512, usually through HMAC if a secret key is involved.

3. Is this only for legacy compatibility? Use the required algorithm, but isolate it and document why it exists.

4. Is this for public file integrity? Publish SHA-256 checksums at minimum.

5. Is output length important? SHA-256 is strong and shorter than SHA-512, which is why it is often the practical default.

The Takeaway

MD5 and SHA-1 belong in the legacy drawer. They can still appear in old systems and non-security workflows, but they should not be chosen for new security-sensitive work.

SHA-256 is the default modern hash for most integrity and signature tasks. SHA-512 is also strong and useful when its longer output and ecosystem fit make sense. For passwords, step away from the plain hash functions and use a real password hashing algorithm.

Hashing looks simple because the output is one neat string. The decision behind that string is where the engineering lives.