Skip to content

Search WPDesignVault

Try "image", "json", "schema" or "contrast". Use arrow keys to move through results.

Developer

SHA-256 vs MD5: Hashing for Checksums, Not Passwords

MD5 is broken for collision resistance; SHA-256 is not, and on our test machine it was faster. Where each fits, how to verify downloads, and why passwords need bcrypt.

Comprehensive guide and visual tutorial explaining sha256 vs md5 for WordPress websites.
On this page

Use SHA-256, not MD5, whenever a hash must resist deliberate tampering: file checksums you publish, signatures, integrity checks and anything security-related. MD5 is broken for collision resistance. RFC 6151 says it "is no longer acceptable where collision resistance is required". It is still acceptable only for non-security jobs such as spotting accidental file corruption or deduplicating cache keys. Neither algorithm is suitable for storing passwords. Both are designed to be fast, so attackers can try enormous numbers of guesses. Passwords need a deliberately slow password-hashing function such as bcrypt or Argon2, which is what WordPress uses.

This post explains what a hash function does and how MD5 and SHA-256 compare. It covers where each still belongs, how to verify a download with a checksum and why passwords are a separate problem. We measured both algorithms on the same machine, along with bcrypt, and checked how WordPress 7.1.3 stores passwords. One result surprises people: on our test hardware, SHA-256 was not slower than MD5 at all.

What a hash function does

A cryptographic hash function turns any input, a word or a 4 GB file, into a fixed-length fingerprint. The same input always gives the same output, and the smallest change produces a completely different one:

SHA-256("hello") = 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
MD5("hello")     = 5d41402abc4b2a76b9719d911017c592

A good hash function has three properties:

  • Pre-image resistance: given a hash, you cannot find an input that produces it.
  • Second pre-image resistance: given an input, you cannot find a different input with the same hash.
  • Collision resistance: you cannot find any two different inputs with the same hash.

MD5 fails the third. Practical collision attacks have been published for years, which means an attacker can create two different files with the same MD5 hash. That breaks any system that trusts an MD5 hash to prove a file has not been swapped.

<h2
Step-by-step workflow architecture diagram for implementing sha256 vs md5 on live sites.
Three-phase workflow architecture diagram for generating, deploying, and testing sha256 vs md5.

MD5 and SHA-256 compared

Table: MD5 versus SHA-256

MD5 SHA-256
Output size 128 bits (32 hex characters) 256 bits (64 hex characters)
Collision resistance Broken No practical attack known
Status RFC 6151: not acceptable where collision resistance is required; must not be used for digital signatures Widely used standard (SHA-2 family)
Speed on our test machine (64 MB, Python) About 534 MB/s About 1,267 MB/s
Available in browsers' Web Crypto API No Yes
Fine for Non-security checks: accidental corruption, cache keys Checksums, signatures, integrity, HMAC
Fine for passwords? No No

The speed result reflects hardware. Many modern processors have instructions that accelerate SHA-256, so the old argument that "MD5 is faster" often no longer holds. Even where MD5 is faster, the difference rarely matters, and SHA-256's security does.

Before you choose

  • Ask what an attacker could gain by making two inputs collide. If anything, use SHA-256.
  • Check what the other side expects. If you are verifying a vendor's checksum, use the algorithm they publish; prefer vendors that publish SHA-256.
  • Separate passwords from everything else. Password storage has its own rules (below).
  • Need a secret key too? Use HMAC-SHA256, which combines a key with the hash, rather than hashing a secret and data together yourself.
<h2
Recommended best practices checklist and common pitfalls to avoid for sha256 vs md5.
Implementation checklist comparing recommended best practices against common errors in sha256 vs md5.

Where each still belongs

Table: Choosing a hash by task

Task Use
Publishing a checksum for a download SHA-256
Verifying a file has not been tampered with SHA-256
Signing data, certificates or tokens SHA-256 (or stronger) inside a signature or HMAC scheme
Spotting accidental corruption in a backup you control MD5 is acceptable; SHA-256 is better and rarely slower
Cache keys, ETags, deduplication with no attacker involved Either; many systems use MD5 for legacy reasons
Storing user passwords Neither: bcrypt, Argon2 or scrypt

Step by step: verify a download with SHA-256

  • Download the file and copy the SHA-256 checksum the publisher lists on their website.
  • Calculate the file's hash. On macOS or Linux, run shasum -a 256 file.zip or sha256sum file.zip. On Windows, run certutil -hashfile file.zip SHA256 in Command Prompt.
  • Compare the two values character by character, or paste both into a text search. They must match exactly.
  • If they differ, do not open the file. Download it again from the official source.

To hash a file or text without the command line, the SHA-256 hash generator works in your browser, supports files up to 200 MB and also offers SHA-384, SHA-512 and SHA-1 (marked legacy). It does not offer MD5, because browsers' built-in crypto does not provide it.

A checksum only helps if it comes from a trusted source. If an attacker can change both the download and the checksum on the same page, a matching hash proves nothing. Signed releases solve that problem.

Why neither is right for passwords

Fast hashes are good for checksums and bad for passwords. If a database of hashed passwords leaks, attackers try billions of guesses and compare hashes. The faster the hash, the faster they can guess. We measured on the same machine:

Table: Hashing speed for a short password (our test machine)

Method Speed or time
MD5 (Python, one core) About 1.1 million hashes per second
SHA-256 (Python, one core) About 1.1 million hashes per second
bcrypt, cost 10 (PHP password_hash) About 72 ms per hash (roughly 14 per second)
bcrypt, cost 12 About 272 ms per hash (roughly 4 per second)

Those single-core figures understate attackers, who use graphics cards and run many guesses in parallel. The gap is the point: bcrypt is tens of thousands of times slower per guess, by design, and its cost can be raised as hardware improves. Password hashing functions also add a random salt to each password, so identical passwords produce different hashes.

What WordPress does

On our WordPress 7.1.3 test site, the administrator's stored password began with $wp$2y$, which marks bcrypt. WordPress core's source code shows that wp_hash_password() uses PHP's password_hash() with bcrypt by default, after pre-hashing the password with HMAC-SHA-384. Older sites may still have older-format hashes, which WordPress upgrades when users log in. If you write your own code, use wp_hash_password() and wp_check_password(), or PHP's password_hash() and password_verify(). Never call md5() or hash( 'sha256', ... ) on passwords.

WordPress's security keys and salts in wp-config.php are a different thing: secrets used to sign login cookies, not to hash passwords. Our guide to wp-config.php settings explains them, and the WordPress salt generator creates new ones.

Worked example: replacing MD5 in a plugin

An illustrative WordPress plugin offers a downloadable report and shows an MD5 hash so users can confirm the file. It also signs download links with md5( $secret . $file_id ).

  • Checksums: switch to hash_file( 'sha256', $path ) and label the value "SHA-256".
  • Signed links: replace the home-made MD5 signature with hash_hmac( 'sha256', $file_id . '|' . $expires, $secret ), include an expiry time, and compare with hash_equals() to avoid timing leaks.
  • Old links: accept both formats for a short transition period, then retire MD5.
  • Test: confirm valid links work, tampered or expired links fail, and the published checksum matches the file.

Verify your use of hashes

  • Search your code for md5( and sha1( and note what each is used for.
  • Replace any security use with SHA-256 or HMAC-SHA256.
  • Confirm passwords go through a password-hashing function only.
  • Compare secret values with constant-time functions such as hash_equals().
  • Publish SHA-256 checksums on the same trusted page as your downloads, and prefer signed releases.

Common mistakes

  • Storing passwords as MD5 or SHA-256 hashes, with or without a salt.
  • Trusting MD5 checksums to detect deliberate tampering.
  • Building "signatures" by hashing a secret plus data instead of using HMAC.
  • Comparing hashes with == instead of a constant-time comparison.
  • Assuming SHA-256 is too slow to use everywhere.
  • Confusing hashing with encryption; hashes cannot be reversed to get the input back.

Troubleshooting

Table: Hash problems and fixes

Symptom Likely cause Fix
Checksum does not match Incomplete or altered download, or the wrong algorithm Check you used SHA-256 if that is what was published; download again from the official source
Same text gives different hashes in two tools Different encoding, trailing newline or whitespace Hash the exact bytes; watch for line endings and UTF-8
Hash generator offers no MD5 Browser crypto APIs do not provide MD5 Use SHA-256, or a command-line tool if you must check a legacy MD5
Users cannot log in after a password migration Old hashes compared with a new function Use a check that accepts the old format and rehashes on login
Signed links can be forged Home-made MD5 signature Switch to HMAC-SHA256 with an expiry

Frequently asked questions

Is MD5 still safe to use?

Not for anything security-related. RFC 6151 says it is not acceptable where collision resistance is required. It is acceptable for spotting accidental corruption or as a non-security cache key.

Is SHA-256 better than MD5?

Yes. It has a longer output and no known practical collision attack, and on modern hardware it is often no slower. In our test it was faster.

Can I use SHA-256 for passwords?

No. It is too fast, which helps attackers guess. Use bcrypt, Argon2 or scrypt, for example through PHP's password_hash().

How does WordPress store passwords?

Current WordPress uses bcrypt through password_hash(), with an HMAC-SHA-384 pre-hash. Stored hashes start with $wp$2y$, as we saw on our WordPress 7.1.3 test site.

Can a hash be reversed?

No. Hashing is one-way. Weak passwords can still be guessed by hashing candidates and comparing, which is why password storage needs slow hashes.

What is a checksum?

A hash of a file that you compare with a published value to confirm the file is complete and unchanged.

What is HMAC?

A way of combining a secret key with a hash function to sign data. HMAC-SHA256 is a common, safe choice for signed links and API requests.

Why is MD5 still used so widely?

Legacy compatibility. Many systems use it for non-security purposes, such as cache keys and ETags, where collisions do not create an attack.

What about SHA-1?

SHA-1 also has practical collision attacks and should not be used for new security purposes. Treat it as legacy, like MD5.

How long is a SHA-256 hash?

256 bits, shown as 64 hexadecimal characters. An MD5 hash is 128 bits, or 32 hex characters.

Next step

Hash a file you download regularly with the SHA-256 hash generator and compare it with the publisher's checksum. If you maintain custom code, search it for md5( and replace any security use. Strong passwords for your own accounts can come from the password generator. More developer explainers are in our developer guides.

SHA-256 Hash Generator

Generate SHA-256, SHA-512, SHA-384 and SHA-1 hashes of text or files to verify downloads and compare data. Everything…

Related articles

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *