About SHA-256 Hash
SHA-256 takes an input of any length and produces a fixed 256-bit digest, written as 64 hexadecimal characters. The same input always gives the same digest, a one-character change gives a completely different one, and there is no way to run the function backwards to recover the input.
Internally it processes the message in 512-bit blocks using 32-bit words, after padding the message and appending its bit length. That padding step is why hashing an empty string still produces a full-length digest rather than nothing.
SHA-256 has no practical attacks against it and is the default choice for new work - content addressing, integrity checks, commitment schemes, and the hash inside most signature and JWT algorithms.
The one thing it is not suitable for is hashing passwords. It is designed to be fast, which is exactly wrong for a password hash - use bcrypt, scrypt or Argon2 there.
SHA-256 is the digest inside most of the machinery you already use: Bitcoin, TLS certificate signatures, JWT HS256 and RS256, Docker image digests, Subresource Integrity, and the SHA-256 checksums published alongside almost every software release. When a specification says only "a secure hash", this is what it means in practice.
This page runs SHA-256 entirely in your browser through the Web Crypto API - the same implementation your browser uses for TLS. Nothing you paste is uploaded, logged, or leaves the tab, which matters when the thing you are hashing is a real token or customer record.
How to use the SHA-256 Hash
- Paste or type your input into the text box - any text, JSON, a token, or a whole file's contents.
- The 256-bit digest is computed as you type and shown as 64 lowercase hex characters.
- Use the copy button to take the digest, and compare it against the value you are checking against.
- Comparing two digests by eye is error-prone - paste both into the Text Diff tool if they are long, or compare the first and last eight characters at minimum.
Examples
-
Input
UUID Studio
SHA-256 Hash in code
The same operation this tool performs, in the languages you are most likely to need it.
const bytes = new TextEncoder().encode("hello world");
const digest = await crypto.subtle.digest("SHA-256", bytes);
const hex = [...new Uint8Array(digest)]
.map((b) => b.toString(16).padStart(2, "0"))
.join("");
console.log(hex); // 64 hex characters
import { createHash } from "node:crypto";
const hex = createHash("sha256").update("hello world").digest("hex");
console.log(hex);
// Large files: stream instead of buffering the whole thing
import { createReadStream } from "node:fs";
import { pipeline } from "node:stream/promises";
const hash = createHash("sha256");
await pipeline(createReadStream("big.tar.gz"), hash);
console.log(hash.digest("hex"));
import hashlib
print(hashlib.sha256(b"hello world").hexdigest())
# Large files: read in chunks so you don't load it all into memory
h = hashlib.sha256()
with open("big.tar.gz", "rb") as f:
for chunk in iter(lambda: f.read(1024 * 1024), b""):
h.update(chunk)
print(h.hexdigest())
import java.security.MessageDigest;
import java.nio.charset.StandardCharsets;
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] digest = md.digest("hello world".getBytes(StandardCharsets.UTF_8));
StringBuilder sb = new StringBuilder();
for (byte b : digest) sb.append(String.format("%02x", b));
System.out.println(sb);
package main
import (
"crypto/sha256"
"encoding/hex"
"fmt"
)
func main() {
sum := sha256.Sum256([]byte("hello world"))
fmt.Println(hex.EncodeToString(sum[:]))
}
using System.Security.Cryptography;
using System.Text;
byte[] digest = SHA256.HashData(Encoding.UTF8.GetBytes("hello world"));
Console.WriteLine(Convert.ToHexString(digest).ToLowerInvariant());
# macOS / Linux
echo -n "hello world" | shasum -a 256 | cut -d" " -f1
# Note the -n: without it, echo appends a newline and you get a
# different digest than every other example on this page.
When you need this
- Verifying a downloaded release against its published SHA-256 checksum.
- Computing a Docker image or content-addressed blob digest.
- Producing a Subresource Integrity value for a script tag.
- Building a deterministic cache key from a serialised payload.
- Reproducing the digest step of a JWT or certificate signature.
Common problems and what causes them
- Using SHA-256 as a MAC by concatenating a secret
- sha256(secret + message) is vulnerable to length extension: an attacker holding a valid digest can append data and compute a valid digest for the longer message without knowing the secret. Use HMAC-SHA256, which is built to prevent exactly this.
- Assuming a SHA-256 digest is a random 256-bit value you can truncate freely
- The digest is uniformly distributed, so truncation is legitimate - but the collision resistance falls to half the retained bits. Truncating to 64 bits gives collisions after roughly 5 billion values, which some systems reach.
- Your digest doesn't match the other system's, for the same input
- Almost always a trailing newline or an encoding difference. `echo "x"` appends \n but `echo -n "x"` does not, and a file saved with CRLF line endings hashes differently from the same file with LF. Hash the exact bytes, not the visually identical text.
- Hex vs Base64 vs raw bytes
- The same 256-bit digest can be printed as 64 hex characters, as Base64, or stored as 32 raw bytes. A mismatch is often just two systems formatting the same digest differently - decode both to bytes before concluding they differ.
- Uppercase vs lowercase hex
- Hex digests are case-insensitive as values but not as strings. `A3F1` and `a3f1` are the same digest and different strings, so a naive `==` comparison fails. Normalise case before comparing.
- Using SHA-256 to hash passwords
- A fast hash is the wrong tool for passwords - commodity hardware computes billions per second, so a leaked table is brute-forced quickly. Use bcrypt, scrypt or Argon2, which are deliberately slow and salted.
- Comparing digests with a non-constant-time comparison
- When you are checking a digest that acts as a secret or a signature, an early-exit string compare leaks how many leading characters matched. Use a constant-time comparison (`crypto.timingSafeEqual`, `hmac.compare_digest`, `MessageDigest.isEqual`).
FAQ
- Why is SHA-256 wrong for passwords when it is cryptographically strong?
- Because it is fast, which is the wrong property here. Commodity GPUs compute billions of SHA-256 hashes per second, so a leaked table of unsalted password digests is cracked quickly. bcrypt, scrypt and Argon2 are deliberately slow and salted.
- What is SHA-256 used for in systems I already rely on?
- TLS certificate signatures, JWT HS256 and RS256, Docker image digests, Subresource Integrity, Bitcoin proof-of-work, and the checksums published with most software releases. When a spec says only "a secure hash", it usually means this one.
- How long is a SHA-256 hash?
- Always 256 bits - 64 hexadecimal characters, or 32 bytes raw - no matter whether the input is one character or a gigabyte.
- Can a SHA-256 hash be decrypted or reversed?
- No. Hashing is not encryption; it discards information and has no key and no inverse. What people mean by "reversing" a hash is looking it up in a precomputed table of common inputs, which is why unsalted hashes of predictable values (short passwords, email addresses) are not private.
- Is SHA-256 safe to use in 2026?
- SHA-256 has no practical attacks against it and is the default choice for new work - content addressing, integrity checks, commitment schemes, and the hash inside most signature and JWT algorithms.
- Why does the same text give a different hash elsewhere?
- Check for a trailing newline, CRLF vs LF line endings, a byte-order mark at the start of the file, or a different character encoding. All of those change the bytes without changing what you see on screen.
- Is this tool sending my input to a server?
- No. The digest is computed in your browser with the Web Crypto API. There is no upload, no request, and no logging - you can confirm it by opening your network tab, or by disconnecting from the network and using the tool offline.
- Should I use SHA-256 or HMAC-SHA-256?
- Use plain SHA-256 when you want an integrity check that anyone can recompute. Use HMAC-SHA-256 when the check has to prove the sender knew a shared secret - webhook signatures, API request signing, tamper-evident tokens. Never hand-roll that as hash(secret + message).
- Is this for passwords?
- Use dedicated password hashing (Argon2, bcrypt). SHA-256 alone is not password storage.