SHA-256 Hash — How It Works and How to Use It in Code
SHA-256 produces a 256-bit (64 hex character) hash. It's used for data integrity verification, digital signatures, and file checksums. Here's how SHA-256 works and how to...
SHA-256 (Secure Hash Algorithm 256-bit) is a cryptographic hash function that produces a fixed 256-bit (32-byte, 64 hex character) output for any input. It’s the most widely used hash for data integrity and digital signatures.
Use the Hash Generator to compute SHA-256 and other hashes online.
SHA-256 properties
SHA-256("hello") = "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"
SHA-256("helo") = "1cd9f9cc91c1b0fa7b18e72b6cefce10d48c4fe9c60869cc0f9e1cd7bf75fc33"
Key properties:
- Fixed output size: always 256 bits (64 hex chars), regardless of input size
- Deterministic: same input always produces the same hash
- Avalanche effect: a one-character change produces a completely different hash
- One-way: cannot reverse a hash to get the original input (in practice)
- Collision resistant: practically impossible to find two inputs with the same hash
JavaScript (Web Crypto API)
The Web Crypto API is available in all modern browsers and Node.js 18+:
// Browser and Node.js 18+:
async function sha256(message) {
const encoder = new TextEncoder();
const data = encoder.encode(message);
const hashBuffer = await crypto.subtle.digest('SHA-256', data);
const hashArray = Array.from(new Uint8Array(hashBuffer));
return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
}
await sha256('hello');
// '2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824'
For files:
async function hashFile(file) {
const buffer = await file.arrayBuffer();
const hashBuffer = await crypto.subtle.digest('SHA-256', buffer);
const hashArray = Array.from(new Uint8Array(hashBuffer));
return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
}
// Usage:
const input = document.querySelector('input[type=file]');
input.addEventListener('change', async () => {
const hash = await hashFile(input.files[0]);
console.log('SHA-256:', hash);
});
Node.js (crypto module)
import { createHash } from 'crypto';
function sha256(data) {
return createHash('sha256').update(data).digest('hex');
}
// String:
sha256('hello');
// '2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824'
// Buffer:
sha256(Buffer.from('hello'));
// File:
import { readFileSync } from 'fs';
sha256(readFileSync('./document.pdf'));
// Stream:
import { createHash } from 'crypto';
import { createReadStream } from 'fs';
async function hashFileStream(path) {
return new Promise((resolve, reject) => {
const hash = createHash('sha256');
createReadStream(path)
.on('data', chunk => hash.update(chunk))
.on('end', () => resolve(hash.digest('hex')))
.on('error', reject);
});
}
Python
import hashlib
# String:
hashlib.sha256(b'hello').hexdigest()
# '2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824'
# With encoding:
hashlib.sha256('hello'.encode('utf-8')).hexdigest()
# File:
def sha256_file(path: str) -> str:
h = hashlib.sha256()
with open(path, 'rb') as f:
while chunk := f.read(65536): # 64KB chunks
h.update(chunk)
return h.hexdigest()
# Bytes:
data = b'\x00\x01\x02\x03'
hashlib.sha256(data).hexdigest()
Common use cases
Data integrity verification
// On upload: store the hash
const file = request.file;
const hash = createHash('sha256').update(file.buffer).digest('hex');
await db.save({ filename: file.originalname, hash, size: file.size });
// On download: verify integrity
const downloadedContent = readFileSync(downloadedPath);
const downloadedHash = createHash('sha256').update(downloadedContent).digest('hex');
if (downloadedHash !== storedHash) {
throw new Error('File integrity check failed');
}
Content-addressable storage
// Use hash as filename — identical files share storage:
async function storeFile(content) {
const hash = await sha256(content);
const path = `./storage/${hash}`;
if (!existsSync(path)) {
writeFileSync(path, content);
}
return hash; // reference by hash
}
API request signing
// Sign API request body:
function signRequest(body, secret) {
return createHmac('sha256', secret)
.update(JSON.stringify(body))
.digest('hex');
}
// Verify on server:
function verifyRequest(body, signature, secret) {
const expected = signRequest(body, secret);
return crypto.timingSafeEqual(
Buffer.from(signature, 'hex'),
Buffer.from(expected, 'hex')
);
}
SHA-256 vs other algorithms
| Algorithm | Output | Speed | Security |
|---|---|---|---|
| MD5 | 128 bits / 32 hex | Fastest | Broken (don’t use for security) |
| SHA-1 | 160 bits / 40 hex | Fast | Deprecated (weak) |
| SHA-256 | 256 bits / 64 hex | Medium | Strong |
| SHA-512 | 512 bits / 128 hex | Slower | Stronger |
| SHA-3-256 | 256 bits / 64 hex | Similar | Different algorithm |
SHA-256 is the best choice for most applications. Use SHA-512 where you need extra margin. Never use MD5 or SHA-1 for security purposes.
Related tools
- Hash Generator — compute SHA-256 and other hashes
- Hash Functions Comparison — MD5 vs SHA-1 vs SHA-256
- HMAC Authentication — keyed hash for API security
Related posts
- MD5 Is Dead. Use These Instead. — MD5 was broken in 2004 and is trivially cracked for passwords. Here's what to us…
- bcrypt Password Hashing — Why You Should Use bcrypt and How to Implement It — bcrypt is the standard password hashing algorithm for web applications. Learn wh…
- File Integrity Verification with Checksums — SHA-256 and MD5 — Verify file integrity using SHA-256 and MD5 checksums. Learn how to generate and…
- Hash Functions Comparison — MD5, SHA-1, SHA-256, bcrypt, Argon2 — Hash functions have different speed, output size, and security properties. MD5 a…
- HMAC Authentication — Signing API Requests with Secret Keys — HMAC (Hash-based Message Authentication Code) signs API requests with a shared s…
Related tool
Generate MD5, SHA-1, SHA-256, and SHA-512 hashes client-side.
Written by Mian Ali Khalid. Part of the Encoding & Crypto pillar.