SHA256 Hash Generator

The same 32 bytes turn up as sha256sum line, certificate fingerprint, Base64 integrity attribute and Docker digest. which is why two correct values look nothing alike. Hash your text or file once here and read every spelling at the same time.

SHA-256 hashing workbench

0 bytes in
Test vectors
Hash a file insteadDrop it here or click to pick one. It is read in the tab, never uploaded.
Type above and the rack fills as you go.
Lowercase hexsha256sum, Git, most APIs
Waiting for input
Colon fingerprintTLS certificates, SSH keys, browser panels
Waiting for input
Base64Integrity attributes, Java, .NET, S3 headers
Waiting for input
Double SHA-256Bitcoin blocks, addresses, transaction ids
Waiting for input
Short digestDocker image ids, cache keys, build tags
Waiting for input

Five values on this page, one digest underneath all of them

A colleague sends a fingerprint with colons in it, the CI log prints 64 plain characters, and the integrity attribute in your HTML holds something ending in an equals sign. Nothing matches, so the natural conclusion is a corrupted download. All three describe the identical 32 bytes written three ways.

SHA-256 produces 256 bits. How those bits reach a screen is a display choice made by whoever wrote the tool:

The same digest, five encodings, and where each one shows up
FormLengthWritten by
Lowercase hex64 characterssha256sum, openssl dgst, Git object ids, most REST APIs
Uppercase hex with colons95 charactersCertificate viewers, ssh-keygen output, Windows certutil
Base6444 characters, ending in =Subresource integrity, Java MessageDigest, the AWS x-amz-checksum-sha256 header
Double SHA-256 hex64 charactersBitcoin block headers, transaction ids, Base58Check
Truncated hex12 characters hereDocker image ids, cache keys, short build tags

The rack above prints all five at once for one reason. Most reported SHA-256 failures are an encoding mismatch rather than a bad file, and seeing the alternatives side by side settles it in a second instead of after an hour of re-downloading.

The sha256- prefix in an integrity attribute is Base64, not hex

Subresource integrity is where the encoding trips people most often. A script tag loading a library from a CDN carries a hash the browser checks before running the file:

<script src="https://cdn.toolexe.com/lib/parser.min.js" integrity="sha256-2mMTz4V0mKfr0kZ1sQhWpVdRUdpCLRfMbYbYb0nX0kM=" crossorigin="anonymous"></script>

The sha256- prefix names the algorithm. What follows is the Base64 row from the rack, never the hex one. Paste 64 hex characters there and the browser blocks the script with a console error about a hash mismatch, while the file itself is perfectly fine.

Two behaviours are worth knowing before you rely on it. The check applies to the response body after decompression, so a CDN switching from gzip to brotli changes nothing. But a CDN that minifies differently, or serves a rolling latest tag, breaks the page outright the moment the bytes shift by one character. Pin an exact version alongside every integrity attribute, and never point one at a URL somebody else revises.

The matching command line, when you want to generate one without this page:

openssl dgst -sha256 -binary parser.min.js | openssl base64 -A

Why Bitcoin runs SHA-256 twice

The fourth row hashes the digest again, SHA-256(SHA-256(input)). Bitcoin does this everywhere, in block headers, in transaction ids, in the checksum bytes of a legacy address, and the reason is a property of the plain construction.

SHA-256 belongs to the Merkle-Damgard family, which carries its internal state straight into the output. Hand somebody SHA-256(secret + message) plus the length of the secret, and they extend it into a valid digest for secret + message + padding + anything without ever learning the secret. Hashing the result a second time hides the state and closes the hole.

Two details catch people reading blockchain data. Bitcoin displays transaction ids in reverse byte order, so the value in a block explorer is the double digest read backwards. And the double digest applies to the raw serialized bytes, not to a hex string of them, which is why hashing the pretty printed hex in a terminal returns an answer nobody recognises.

If you reached for double hashing to protect an API signature, reach for HMAC-SHA256 instead. It solves the same state leak with a reviewed construction, and every language ships it in the standard library.

What a certificate fingerprint covers, and what it does not

The colon row matches what a browser certificate panel shows, and what openssl x509 -fingerprint -sha256 prints. The digest covers the DER encoding of the whole certificate, so it changes on renewal even when the key stays identical and the domain never moves.

This matters for pinning. Pin a certificate fingerprint in a mobile app and the app stops trusting your own server on the next renewal, which with a 90 day certificate arrives fast. Pinning the public key digest survives renewal, since the key is the part being reused. Both leave you locked out if the key is ever rotated in an emergency, which is why a backup pin is standard practice.

To reproduce the row for a live host:

openssl s_client -connect toolexe.com:443 -servername toolexe.com < /dev/null 2>/dev/null \ | openssl x509 -noout -fingerprint -sha256

SSH does it differently again. ssh-keygen -lf prints SHA256: followed by Base64 with the padding stripped, so the value in a known_hosts prompt is the Base64 row minus its trailing equals sign.

Where SHA-256 is the wrong tool

Storing passwords is the biggest one. SHA-256 is built for speed, and a rented GPU rig runs billions of guesses per second against it. Adding a salt stops a rainbow table and does nothing about the throughput. Password storage needs a function designed to be slow and memory hungry: Argon2id first, with bcrypt and scrypt as accepted alternatives, all of which handle their own salting.

A few more places where a plain digest disappoints:

  • Signing an API request. Use HMAC-SHA256 with a shared key. A bare digest of the body proves nothing about who sent it.
  • Deduplicating near identical files. One flipped bit rewrites every character of the output, so a digest answers identical or not, never how close.
  • Short identifiers. The truncated row suits a cache key and nothing security related. Twelve hex characters is 48 bits, and birthday collisions arrive around 16 million entries.
  • Hiding a small value. Digests of phone numbers, email addresses or card numbers fall to brute force in minutes, because the input space is tiny.

Where SHA-256 belongs: release checksums, content addressing, integrity attributes, Merkle trees, commit ids, exact match deduplication, and as the hash inside HMAC and TLS signatures.

Matching this page from a terminal

Every row is reproducible locally, worth doing once so you trust the output later:

sha256sum release.tar.gz # Linux, lowercase hex shasum -a 256 release.tar.gz # macOS certutil -hashfile release.tar.gz SHA256 # Windows, uppercase hex Get-FileHash release.tar.gz -Algorithm SHA256 # PowerShell printf 'abc' | sha256sum # text with no trailing newline

The last line is the one people get wrong. echo abc appends a newline, so it hashes four bytes rather than three and returns a digest nothing else agrees with. Reach for printf, or echo -n, whenever you compare a text digest against this page.

What this page will not do

  • Files past roughly 2 GB are refused. Web Crypto needs the whole file in memory at once, so a disk image belongs with sha256sum.
  • No streaming progress on the hash itself. The bar tracks reading the file, then the digest happens in one call.
  • No keyed output. HMAC-SHA256 needs a secret and lives on its own page.
  • No reversing. Nothing recovers an input from a digest, here or anywhere, and a site claiming otherwise is running a lookup table of common strings.
  • Line endings are hashed as they arrive. A file saved with CRLF on Windows and LF on Linux produces two different digests from identical looking text.

Hashing calls crypto.subtle.digest in your browser and files are read through FileReader, so nothing is sent anywhere. Load the page once, cut the connection, and it keeps working.

SHA-256 questions from real support threads

Why does my Base64 hash look shorter than the hex one?

Base64 packs three bytes into four characters, so 32 bytes become 44 characters ending in a single equals sign, against 64 characters in hex. Both describe the same digest. Java MessageDigest, .NET and subresource integrity attributes default to Base64, while sha256sum and most APIs default to hex.

The checksum I pasted does not match. Is the file corrupt?

Check the encoding first. A value with colons, a value ending in an equals sign and a plain 64 character string are three spellings of one digest, and the rack above prints all of them. If the lowercase hex row still disagrees, the download differs from the published file and is worth fetching again from the original source.

Is SHA-256 broken or close to it?

No. The best public attacks reach roughly 31 of the 64 rounds and produce nothing usable against the full function. SHA-1 fell because collisions became affordable, and SHA-256 has no equivalent result. It is the default choice for new work today, with SHA-3 and SHA-512/256 as alternatives when you want a different internal design.

Should I use SHA-256 to store user passwords?

No. Speed is the point of SHA-256 and the enemy of password storage. A rented GPU tests billions of candidates per second against it, salted or not. Argon2id is the current recommendation, with bcrypt and scrypt as accepted alternatives. All three deliberately cost time and memory per guess.

What is the difference between SHA-256 and SHA-2?

SHA-2 is the family name. It covers SHA-224, SHA-256, SHA-384, SHA-512 and the two truncated SHA-512 variants. SHA-256 is the 256-bit member, and the one people mean when a document says SHA-2 without a number.

Why is the double SHA-256 row different from the plain one?

It hashes the first digest again, which is what Bitcoin does for block headers and transaction ids. The second pass hides the internal state behind the length extension weakness in plain SHA-256. Comparing a Bitcoin value against the plain hex row will never match.

Does hashing a 4 GB file work here?

No. The browser holds the whole file in memory for the digest call, so anything past roughly 2 GB fails or crashes the tab. Run sha256sum, certutil or Get-FileHash locally for large images, all of which stream the file in chunks.

Are my text and files sent to a server?

No. The digest comes from the Web Crypto API inside the tab and files are read with FileReader. There is no upload step, which makes a private key, an internal build or a customer export safe to check here.