Skip to content
Back to Blog
Security

Convert MD5 to SHA-256? Why It's Impossible (and What to Do Instead)

You can't convert an MD5 hash to SHA-256 — hashing is one-way. See what hash converter pages really do and the right fix for each task. Free online tools.

11 min read

Convert MD5 to SHA-256? Why It’s Impossible (and What to Do Instead)

Plenty of pages promise to do it, and some of them look like working tools. The operation they advertise does not exist, and what you should do instead depends on why you wanted it.

The short answer: you can’t convert MD5 to SHA-256 (or SHA-256 to MD5)

No, and it is not a tooling gap that somebody will close later. An MD5 digest is 128 bits of output that does not contain the input that produced it. SHA-256 needs that input to compute anything at all. Without the original data the middle step is permanently missing, and no tool or library fills it in.

Here is the same input under three algorithms:

AlgorithmDigest of helloHex charsBits
MD55d41402abc4b2a76b9719d911017c59232128
SHA-1aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d40160
SHA-2562cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b982464256

Look at the three digests as strings. They share no prefix and no substring, and no arithmetic turns one into another. The only thing connecting them is the word hello, and not one of them carries it. Compute them yourself with the MD5 hash generator and the SHA-256 generator if you want to watch both change independently as you type.

Direction makes no difference either. Going from SHA-256 to MD5 fails for exactly the same reason: both functions destroy information on purpose, so neither digest can be walked back to the input the other one would need.

Nobody types this query out of curiosity about hash theory. It comes from one of four tasks, and each has a real answer:

  1. Verifying a download or comparing checksums
  2. Migrating a password database off MD5
  3. Recovering the original input behind a hash
  4. Getting the same data hashed under a different algorithm

Before those, it helps to be able to spot a converter page for what it is.

What an “MD5 to SHA-256 converter” page actually does

There are only three possibilities, and none of them is a conversion.

Most of them ask you for the original text. You paste a string, the page produces both digests, and the marketing copy calls it a conversion. It is a hash generator with a misleading label. Nothing was converted; the input was hashed twice.

Some look the digest up. The page keeps a table of input-to-digest pairs harvested from wordlists and leaked credential dumps. Paste an MD5 whose input is in that table, and the page finds the input, then hashes it with SHA-256 and shows you the result. This works for password, 123456, and a long tail of other short strings. It fails silently on anything else, which is why these pages often return a blank result with no explanation.

A surprising number do nothing at all. They re-display your input, or emit a SHA-256 of the hex string you pasted while implying it is the SHA-256 of your original data. Those two values are different, and the section on double-hashing below shows exactly how different.

The test is quick. Give the page a 32-character hex string and nothing else, and ask whether it could possibly know the input. If it returns a 64-character result anyway and calls that a conversion, it is either querying a lookup table or lying to you. A hash converter that never asks for your original data has no way to be right except by coincidence.

The phrasing survives because it sounds like something adjacent that genuinely works: encoding.

Hashing, encoding, and encryption: only two of the three are reversible

Developers meet all three of these in the same week and file them in the same mental drawer. They behave completely differently:

OperationExampleReversible?What you need
EncodingBase64, hex, URL-encodingYes, alwaysNothing at all
EncryptionAES, RSAYesThe key
HashingMD5, SHA-1, SHA-256NeverNothing helps

Base64 is the one that trains the wrong intuition. Anyone can decode a Base64 string back to its bytes with no key and no permission, and converting Base64 to hex is a legitimate, everyday operation. Both are just alternative spellings of the same bytes. If you have seen that work, “MD5 to SHA-256” sounds like the same kind of re-spelling.

It is not. Encoding preserves every bit of the input, encryption preserves it behind a key, and hashing throws almost all of it away. An MD5 digest is 16 bytes no matter whether you fed it a password or a 40 GB disk image. The 40 GB did not go anywhere clever; it is gone. The MD5 tool’s FAQ covers the encryption comparison in more detail if you want it, but the one-line version is enough here: there is no key, so there is nothing to decrypt.

”MD5 is broken” does not mean “MD5 is reversible”

Even careful articles get this wrong, because people reason from “MD5 was broken years ago” straight to “so surely somebody can undo it by now.”

Two different attacks get mixed up here:

  • A collision attack finds two different inputs that produce the same digest. The attacker chooses both inputs and does not care what they are.
  • A preimage attack starts from a digest and recovers an input that produces it. This is the one that would let you convert MD5 to SHA-256, because it would hand you back something to feed into SHA-256.

MD5’s collision resistance fell in 2004, and today a collision can be constructed on ordinary hardware in seconds. That is why MD5 is unfit for signatures, certificates, and anything an adversary can influence.

MD5’s preimage resistance has not fallen. The best known preimage attack remains theoretical, with a complexity of 2^123.4 (Sasaki and Aoki, 2009). That is faster than brute force by a hair and unreachable by any margin that matters. Nobody is inverting arbitrary MD5 digests, in 2004 or now.

So the two facts sit side by side without contradiction: MD5 is broken, and MD5 is still not reversible. If you are choosing between the two algorithms for a new system rather than trying to convert between them, the MD5 vs SHA-256 comparison covers that decision properly.

The four tasks behind this search, and what to do for each

What you are really doingWhat to do instead
Verifying a download or comparing checksumsRecompute from the file with the algorithm you need
Migrating MD5 password hashesWrap them in bcrypt and upgrade on login
Recovering the original inputThat is cracking, not converting, and it depends on entropy
Re-hashing the same data under another algorithmGo back to the source bytes

Task 1: You are comparing checksums or verifying a download

Recompute, do not convert. You have the file sitting on disk, which means you have the one thing the digest lost. Run whichever algorithm you need against it:

# GNU coreutils
md5sum    ubuntu-24.04-desktop-amd64.iso
sha256sum ubuntu-24.04-desktop-amd64.iso

# macOS
md5           ubuntu-24.04-desktop-amd64.iso
shasum -a 256 ubuntu-24.04-desktop-amd64.iso

The mismatch people run into is a publisher who lists only an MD5 while your security policy demands SHA-256. Converting the published MD5 would prove nothing even if it were possible, because a digest you derived from another digest is not a statement by the publisher about the file. What you need is a SHA-256 that the publisher signed. If they do not offer one, computing your own SHA-256 with the SHA-256 generator still gives you a stable fingerprint for internal use: you can pin it, compare it across mirrors, and detect changes later. It just cannot substitute for the publisher’s attestation.

Task 2: You are migrating a password database off MD5

This is the task with the most at stake, and it has a well-worn solution: wrap the old hashes, then upgrade each account transparently at login. You bcrypt every stored MD5 hash in a single batch job, and from then on the login path MD5s the submitted password first and compares that against the bcrypt record.

One warning first, because a lot of older advice gets this backwards. Wrapping MD5 in SHA-256 does not make password storage safe. SHA-256 is a fast hash, the same category of problem as MD5, and GPUs chew through both at enormous rates. Advice that points you at a database’s built-in SHA2() function as the fix is solving the wrong problem. The target is a deliberately slow hash: bcrypt, scrypt, or Argon2. Store bcrypt(md5(password)), never sha256(md5(password)). The bcrypt vs Argon2 vs scrypt comparison covers how to pick among the three, and the bcrypt generator lets you test cost factors before you commit to one.

Now the part that actually breaks migrations. “The MD5 of the password” is ambiguous, and the two readings produce different results:

const { createHash } = require('node:crypto');

const md5Hex = createHash('md5').update('hello').digest('hex');
const md5Raw = createHash('md5').update('hello').digest();   // the same value as 16 bytes

createHash('sha256').update(md5Hex).digest('hex');
// 4914e23374bb211e3dca0df7636fefffc7fedd94f1340ae81c7d6c07b7113e9b

createHash('sha256').update(md5Raw).digest('hex');
// 88e20f0abb88153e3f0a9683668ccb5b84ed771817dc448a2b73254ed02c8d8c

createHash('sha256').update('hello').digest('hex');
// 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824

Three results, all correct, all different. Hash the 32-character hex string and you get one value; hash the 16 raw bytes it represents and you get another; hash the original password and you get a third. Pick a convention, write it down, and use the same one in the migration script and the login path. Getting this wrong locks out every user at once, and the symptom looks like a bcrypt bug rather than an encoding decision.

For a bcrypt wrapper, hex is the safer convention. Raw digest bytes can contain a zero byte, and several bcrypt implementations treat their input as a C string and stop reading there. Hex avoids that entirely, and at 32 characters it stays well under bcrypt’s input length limit. Normalize the case too, since 5D41402A... and 5d41402a... are different strings to bcrypt even though they are the same digest.

const bcrypt = require('bcrypt');
const { createHash } = require('node:crypto');

const legacyDigest = (password) =>
  createHash('md5').update(password, 'utf8').digest('hex');   // lowercase hex

// Batch job, run once: wrap each stored MD5, then drop the old column.
async function wrapRow(row) {
  return bcrypt.hash(row.md5_hash.toLowerCase(), 12);
}

// Login path
async function verify(password, row) {
  if (row.scheme === 'bcrypt') {
    return bcrypt.compare(password, row.hash);
  }
  const ok = await bcrypt.compare(legacyDigest(password), row.hash);
  if (ok) {
    const upgraded = await bcrypt.hash(password, 12);
    await saveCredential(row.id, { scheme: 'bcrypt', hash: upgraded });  // your DB write
  }
  return ok;
}

Accounts move to plain bcrypt as their owners sign in. Set a deadline for the stragglers and force a reset after it.

Task 3: You are trying to recover the original input

Say so plainly, at least to yourself, because it changes the tooling and the expectations. Recovering an input from a digest is cracking, not converting, and whether it works has nothing to do with which algorithm produced the digest. It depends on the input.

Short, common, human-chosen strings fall quickly. Dictionary words, names with a digit on the end, and anything that has appeared in a breach corpus give way to a lookup or a short brute-force run. Long random strings do not fall at all, and the gap between the two cases is not a matter of buying more hardware.

The usual description of rainbow tables is too loose. A rainbow table recovers an input only when that input was hashed without a salt and is already present in the table. Both conditions are required. Add a per-user salt and the precomputed table is worthless, because the attacker would need a separate table per salt. Feed the hash a 128-bit random token and no table on earth contains it. The password entropy guide puts numbers on where the boundary sits.

If the input was a password you own and you cannot reproduce it, treat this as a reset, not a recovery. If it belongs to someone else, the honest framing is the one above.

Task 4: You need the same data hashed with a different algorithm (“md5 to sha1 converter”)

Same shape as Task 1, generalized. The pair of algorithms in the request does not matter, because the answer is always to go back to the source bytes and hash them again:

sha1sum   payload.bin
sha256sum payload.bin

Every “md5 to sha1 converter” you find is a re-hasher or a lookup table, for the same reasons covered above. If the original data is gone, so is the answer. Pick the target algorithm with the SHA family comparison; the SHA-1 generator is there for legacy systems that still require it, though nothing new should.

The one case where a hash converter lookup actually works

Some classes of data are collected centrally and indexed by every common digest at once. Malware samples are the standard example. Services like VirusTotal store the sample itself, so they have computed its MD5, SHA-1, and SHA-256 from the same bytes and filed all three against one record. Search a sample’s MD5 there and you get its SHA-256 back.

That is a database join, not a conversion. It works because somebody had the original file and hashed it with every algorithm, exactly the recompute step described above, just done in advance by a third party. The conditions are strict: the object must already be in the index, and you have to trust whoever built it. Threat-intel workflows depend on this daily. It says nothing about arbitrary MD5 digests, and it will never help with a hash of your own data.

The mechanism is the same one the sketchy converter pages use. The difference is that a malware repository tells you it is a lookup and shows you the record.

Try it yourself

This is easier to see than to argue about. Hash the same string with both algorithms:

$ printf 'hello' | md5sum
5d41402abc4b2a76b9719d911017c592  -
$ printf 'hello' | sha256sum
2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824  -

Change one character and both outputs change completely, in ways that have nothing to do with each other. Paste the same text into the MD5 hash generator and the SHA-256 generator side by side to see it live, or reach for the HMAC generator when what you actually need is a keyed digest for signing an API request. All three run entirely in your browser.

FAQ

Can you convert MD5 to SHA-256?

No. An MD5 digest does not contain the original input, and SHA-256 needs that input to produce anything. Any page claiming to convert is either re-hashing text you supply or looking the value up in a database of precomputed pairs.

Why do so many sites offer an “MD5 to SHA-256 converter”?

They rank for a query people type. Once you land there, the page either asks for your original text, which makes it a re-hash rather than a conversion, or returns nothing useful. The demand is real even though the operation is not.

Is it possible to convert SHA-256 back to MD5?

No, and the direction does not matter. Both are one-way functions, so neither digest can be turned into the other without the original input. A tool offering the reverse trip is running the same lookup or re-hash trick.

MD5 is broken, so doesn’t that mean it can be reversed?

No. MD5’s collision resistance fell in 2004, meaning two inputs can be forced to share a digest. Reversing a digest is a preimage attack, and the best known one still costs 2^123.4 operations. MD5 is broken for signatures and still not invertible.

How do I migrate a database of MD5 password hashes to something safer?

In MySQL the obvious one-liner, UPDATE users SET password = SHA2(password, 256), is wrong — it hashes the stored MD5 digest rather than the password, so store bcrypt(md5(password)) and verify through the same wrapper, upgrading each record on the next successful login. Wrapping MD5 in SHA-256 does not help, because both are fast hashes and a GPU handles either at the same brutal rate.

Why did double-hashing give me a different result than expected?

Hashing the MD5 hex string and hashing its raw 16 bytes produce different SHA-256 outputs. Both are valid; they are just different inputs. Pick one convention and apply it identically in the migration script and the login path.

Can a rainbow table recover the input behind an MD5 hash?

Only when the input was unsalted and is already present in the table, which in practice means short or common strings. Long random inputs are not recoverable this way, and adding a per-user salt defeats precomputed tables entirely.

Is there an MD5 to SHA-1 converter?

No. Every “MD5 to SHA-1 converter” is a re-hasher or a lookup table, because the same one-way property blocks MD5 to SHA-1 exactly as it blocks MD5 to SHA-256. With the original input you can recompute it using the SHA-1 generator; without it, nothing can.

Tags: md5 sha-256 hashing security checksum cryptography

Related Articles

View all articles