MD5 vs SHA-256: który algorytm hash wybrać?
Obliczanie hashu to jedna z najbardziej fundamentalnych operacji w informatyce — jednak wybór niewłaściwego algorytmu może narazić system na ataki kolizyjne, uszkodzenie danych lub zbędny narzut wydajnościowy. Ten przewodnik porównuje cztery najczęściej używane algorytmy hash i przedstawia jasny schemat decyzyjny.
Czym jest funkcja hashująca?
Kryptograficzna funkcja hashująca przyjmuje dowolne dane wejściowe i produkuje wynik o stałym rozmiarze („digest” lub „hash”). Dobre funkcje hashujące mają trzy własności:
- Determinizm: te same dane wejściowe zawsze dają ten sam wynik.
- Jednokierunkowość: nie da się odwrócić hashu, aby odzyskać oryginalne dane wejściowe.
- Odporność na kolizje: znalezienie dwóch różnych danych wejściowych dających ten sam hash powinno być obliczeniowo niewykonalne.
Gdy własność nr 3 zostaje złamana, algorytm uznaje się za „kryptograficznie złamany” — dokładnie to spotkało MD5 i SHA-1.
Porównanie algorytmów w skrócie
| Własność | MD5 | SHA-1 | SHA-256 | SHA-512 |
|---|---|---|---|---|
| Rozmiar wyniku | 128 bitów (32 znaki hex) | 160 bitów (40 znaków hex) | 256 bitów (64 znaki hex) | 512 bitów (128 znaków hex) |
| Rozmiar bloku | 512 bitów | 512 bitów | 512 bitów | 1024 bity |
| Rok wprowadzenia | 1991 | 1995 | 2001 | 2001 |
| Projektant | Ron Rivest | NSA / NIST | NSA / NIST | NSA / NIST |
| Odporność na kolizje | Złamany (2004) | Złamany (2017) | Bezpieczny | Bezpieczny |
| Szybkość (względna) | Najszybszy | Szybki | Umiarkowany | Umiarkowany (szybszy na 64-bit) |
| Status NIST | Wycofany | Wycofany | Zalecany | Zalecany |
MD5: szybki, ale złamany
MD5 (Message-Digest Algorithm 5) został zaprojektowany przez Ronalda Rivesta w 1991 roku i przez całe lata 90. oraz początek lat 2000 stanowił de facto standard dla sum kontrolnych. Tworzy 128-bitowy hash w postaci 32 znaków szesnastkowych.
Dlaczego MD5 jest złamany
W 2004 roku Xiaoyun Wang zademonstrowała praktyczne ataki kolizyjne na MD5. W 2008 roku badacze utworzyli fałszywy certyfikat SSL z wykorzystaniem kolizji MD5, dowodząc, że atak nie jest jedynie teoretyczny. Obecnie kolizje MD5 można wygenerować w ciągu kilku sekund na sprzęcie konsumenckim.
// Generate an MD5 hash (for non-security use only)
// Using the Web Crypto API is not available for MD5 — use a library
import { md5 } from 'hash-wasm';
const hash = await md5('Hello, World!');
console.log(hash);
// → 'bea8252ff4e80f41719ea13cdf007273' (32 hex chars)
Kiedy MD5 jest jeszcze akceptowalny
Pomimo bycia kryptograficznie złamanym, MD5 pozostaje przydatny w zastosowaniach bez wymagań bezpieczeństwa:
- Deduplikacja plików: wykrywanie zduplikowanych plików w systemach pamięci masowej
- Klucze cache: generowanie krótkich, deterministycznych kluczy do wyszukiwań w cache
- Sumy kontrolne integralności danych: szybka weryfikacja, że dane nie zostały przypadkowo uszkodzone (a nie celowo zmanipulowane)
- Zgodność z systemami legacy: współpraca ze starszymi systemami wymagającymi MD5
Kluczowe rozróżnienie: MD5 chroni przed przypadkowym uszkodzeniem, ale nie przed celową manipulacją.
SHA-1: wycofany, lecz wciąż obecny
SHA-1 (Secure Hash Algorithm 1) został zaprojektowany przez NSA i opublikowany przez NIST w 1995 roku. Tworzy 160-bitowy hash w postaci 40 znaków szesnastkowych.
W 2017 roku Google i CWI Amsterdam zademonstrowali pierwszą praktyczną kolizję SHA-1 (atak „SHAttered”), generując dwa różne pliki PDF o tym samym hashu SHA-1. Główne przeglądarki i urzędy certyfikacji już od 2016 roku zaczęły odrzucać certyfikaty SHA-1.
SHA-1 należy stosować wyłącznie dla zgodności z systemami, które tego wymagają (np. Git używa SHA-1 dla hashy commitów, choć przechodzi na SHA-256). Dla każdego nowego rozwoju trzeba wybrać SHA-256 lub mocniejszy.
SHA-256: aktualny standard
SHA-256 należy do rodziny SHA-2, zaprojektowanej przez NSA i opublikowanej przez NIST w 2001 roku. Tworzy 256-bitowy hash w postaci 64 znaków szesnastkowych i w 2026 roku jest zalecanym algorytmem dla praktycznie wszystkich zastosowań hash.
// Generate a SHA-256 hash using the Web Crypto API (browser-native)
async function sha256(text) {
const data = new TextEncoder().encode(text);
const hash = await crypto.subtle.digest('SHA-256', data);
return Array.from(new Uint8Array(hash))
.map(b => b.toString(16).padStart(2, '0'))
.join('');
}
const hash = await sha256('Hello, World!');
console.log(hash);
// → 'dffd6021bb2bd5b0af676290809ec3a53191dd81c7f70a4b28688a362182986f'
Dlaczego SHA-256 to wybór domyślny
- Brak znanych ataków: na rok 2026 nie istnieją praktyczne ataki kolizyjne ani preimage
- Wbudowany w przeglądarce: dostępny przez Web Crypto API we wszystkich nowoczesnych przeglądarkach — bez bibliotek
- Standard branżowy: używany przez certyfikaty TLS, Bitcoin, menedżery pakietów (npm, pip), digesty obrazów Docker i większość systemów weryfikacji integralności
- Zatwierdzony przez NIST: zalecany dla wszystkich zastosowań wrażliwych na bezpieczeństwo
SHA-512: gdy potrzeba więcej
SHA-512 tworzy 512-bitowy hash w postaci 128 znaków szesnastkowych. Wykorzystuje rozmiar bloku 1024 bity (wobec 512 bitów w SHA-256), co czyni go szybszym od SHA-256 na procesorach 64-bitowych, ponieważ przetwarza więcej danych w jednym cyklu.
# Python: SHA-512 is just as easy as SHA-256
import hashlib
hash_256 = hashlib.sha256(b'Hello, World!').hexdigest()
hash_512 = hashlib.sha512(b'Hello, World!').hexdigest()
print(f"SHA-256: {hash_256}") # 64 chars
print(f"SHA-512: {hash_512}") # 128 chars
SHA-512 należy stosować, gdy:
- potrzebny jest większy margines bezpieczeństwa (256-bitowa odporność na kolizje wobec 128-bitowej w SHA-256)
- platforma jest 64-bitowa, a wydajność ma znaczenie (SHA-512 może być nawet 1,5 raza szybszy od SHA-256 na x86-64)
- protokół lub specyfikacja tego wymagają (niektóre schematy certyfikatów, konkretne wymagania zgodności)
W większości zastosowań SHA-256 jest wystarczający. Dodatkowa długość hashy SHA-512 podwaja zapotrzebowanie na pamięć i przepustowość bez praktycznej korzyści w zakresie bezpieczeństwa dla typowych przypadków użycia.
Schemat decyzyjny: który hash wybrać
Dla integralności plików i sum kontrolnych
Należy używać SHA-256. To standard weryfikacji pobrań, porównywania zawartości plików i sprawdzania, czy dane nie zostały uszkodzone. Przy zastępowaniu istniejącego systemu opartego na MD5, SHA-256 jest bezpośrednim zamiennikiem.
# Verify a download's integrity
sha256sum downloaded-file.tar.gz
# Compare output against the published hash
Dla przechowywania haseł
Nie należy używać MD5 ani SHA-256 bezpośrednio. Funkcje hash ogólnego przeznaczenia są zbyt szybkie do hashowania haseł — atakujący może podejmować miliardy prób na sekundę. Zamiast tego trzeba zastosować dedykowany algorytm hashowania haseł:
| Algorytm | Status | Uwagi |
|---|---|---|
| Argon2id | Zalecany | Zwycięzca Password Hashing Competition 2015; memory-hard |
| bcrypt | Dobry | Szeroko wspierany; wbudowana sól; konfigurowalny work factor |
| scrypt | Dobry | Memory-hard; używany przez niektóre systemy kryptowalut |
| PBKDF2 | Akceptowalny | Zatwierdzony przez NIST, lecz nie memory-hard; należy użyć ≥600 000 iteracji |
| SHA-256 | Niewystarczający | Zbyt szybki; brak wbudowanej soli; podatny na ataki GPU |
| MD5 | Niebezpieczny | Złamany + zbyt szybki; trywialnie łamliwy |
// WRONG: Don't hash passwords with SHA-256
const hash = await sha256(password); // Crackable at billions/sec
// RIGHT: Use bcrypt (Node.js example)
import bcrypt from 'bcrypt';
const hash = await bcrypt.hash(password, 12); // 12 rounds = ~250ms
const isValid = await bcrypt.compare(input, hash);
Dla HMAC i uwierzytelniania wiadomości
Należy używać SHA-256 z HMAC. HMAC (Hash-based Message Authentication Code) łączy funkcję hashującą z tajnym kluczem w celu weryfikacji zarówno integralności, jak i autentyczności:
// HMAC-SHA256 for webhook signature verification
async function verifyWebhook(payload, signature, secret) {
const key = await crypto.subtle.importKey(
'raw', new TextEncoder().encode(secret),
{ name: 'HMAC', hash: 'SHA-256' }, false, ['verify']
);
const sig = Uint8Array.from(atob(signature), c => c.charCodeAt(0));
return crypto.subtle.verify('HMAC', key, sig, new TextEncoder().encode(payload));
}
Dla pamięci adresowanej zawartością
Należy używać SHA-256. Git, Docker i IPFS używają pamięci adresowanej zawartością, w której hash zawartości pełni funkcję jej adresu. SHA-256 zapewnia odporność na kolizje wystarczającą do zagwarantowania unikalności wśród miliardów obiektów.
Benchmarki wydajnościowe
Względna szybkość obliczania hashu na nowoczesnym procesorze x86-64 (wyższa = szybsza):
| Algorytm | Przepustowość (MB/s) | Względna szybkość |
|---|---|---|
| MD5 | ~3 200 | 1,0x (linia bazowa) |
| SHA-1 | ~2 400 | 0,75x |
| SHA-256 | ~1 500 | 0,47x |
| SHA-512 | ~2 100 | 0,66x |
Uwaga: SHA-512 jest szybszy od SHA-256 na procesorach 64-bitowych dzięki szerszemu stanowi wewnętrznemu. Na systemach 32-bitowych sytuacja się odwraca. Dla większości zastosowań różnica w szybkości jest nieistotna — obliczenie hashu z pliku o rozmiarze 1 MB zajmuje poniżej 1 ms dowolnym z tych algorytmów.
Najczęstsze błędy, których trzeba unikać
1. Używanie MD5 do bezpieczeństwa
Kolizje MD5 są trywialne do wygenerowania. Nigdy nie należy używać MD5 do podpisów cyfrowych, walidacji certyfikatów ani żadnego scenariusza, w którym atakujący mógłby spreparować złośliwe dane wejściowe.
2. Obliczanie hashu haseł algorytmem SHA-256
SHA-256 nie jest hashem haseł. Jest zbyt szybki, nie ma wbudowanej soli i jest podatny na ataki z użyciem rainbow tables oraz brute-force przyspieszanego przez GPU. Należy użyć Argon2id lub bcrypt. Aby zrozumieć dlaczego, warto zajrzeć do naszego przewodnika o entropii hasła — wyjaśnia matematykę odporności na brute-force.
3. Założenie, że długość hashu odpowiada bezpieczeństwu
512-bitowy hash nie jest automatycznie „bezpieczniejszy” od 256-bitowego pod kątem odporności na kolizje. Margines bezpieczeństwa SHA-256 (128-bitowa odporność na kolizje) znacznie przekracza możliwości brute-force. Wybór należy oprzeć na rzeczywistych wymaganiach, a nie na długości hashu.
4. Wymyślanie własnych kombinacji hashy
Schematy w stylu SHA256(MD5(data)) lub MD5(data + salt) nie naprawiają w magiczny sposób złamanego algorytmu. Zamiast tego należy użyć jednego, dokładnie sprawdzonego algorytmu (SHA-256) lub poprawnej konstrukcji (HMAC).
Wypróbuj samodzielnie
Wygeneruj i porównaj natychmiast hashe MD5, SHA-1, SHA-256 i SHA-512 za pomocą naszego generatora hashy — wystarczy wkleić tekst lub przeciągnąć plik, a wszystkie cztery digesty wyświetlą się obok siebie. 100% w przeglądarce, dane nigdy nie opuszczają urządzenia.
Aby uzyskać szerszy obraz bezpieczeństwa webowego, w tym uwierzytelniania, walidacji danych wejściowych i nagłówków bezpieczeństwa, warto przeczytać nasz przewodnik podstawy bezpieczeństwa webowego. Można także zapoznać się z naszymi narzędziami dla programistów do kodowania, obliczania hashy i konwersji danych.
Często zadawane pytania
Czy MD5 jest jeszcze bezpieczny dla sum kontrolnych?
MD5 jest bezpieczny do wykrywania przypadkowego uszkodzenia plików — jeśli plik zostanie uszkodzony podczas pobierania, hash MD5 niemal na pewno się zmieni. MD5 nie jest jednak bezpieczny wobec celowej manipulacji, ponieważ atakujący może spreparować zmodyfikowany plik o tym samym hashu MD5. Do weryfikacji integralności w warunkach, w których adwersarz stanowi zagrożenie (np. dystrybucja oprogramowania), trzeba użyć SHA-256.
O ile SHA-256 jest wolniejszy od MD5?
SHA-256 jest około 2 razy wolniejszy od MD5 pod względem surowej przepustowości. Na nowoczesnym sprzęcie MD5 osiąga około 3 200 MB/s, a SHA-256 około 1 500 MB/s. W praktyce różnica ta jest pomijalna dla większości zastosowań — obliczenie hashu z pliku o rozmiarze 100 MB zajmuje SHA-256 około 70 ms. Luka wydajnościowa ma znaczenie tylko w scenariuszach o bardzo wysokiej przepustowości, takich jak inspekcja pakietów sieciowych czy deduplikacja pamięci masowej na dużą skalę.
Czy lepiej użyć SHA-256, czy SHA-512 dla mojej aplikacji?
W większości zastosowań SHA-256 jest wystarczający — zapewnia 128-bitową odporność na kolizje, znacznie przekraczającą możliwości brute-force. SHA-512 warto wybrać, gdy: (a) platforma jest 64-bitowa i potrzeba maksymalnej przepustowości, (b) specyfikacja lub wymagania zgodności tego nakazują, lub (c) potrzebny jest większy margines bezpieczeństwa dla długoterminowej integralności danych. Dodatkowa długość hashu SHA-512 podwaja zapotrzebowanie na pamięć i rzadko jest konieczna.
Czy SHA-256 da się złamać lub odwrócić?
SHA-256 nie da się odwrócić — jest funkcją jednokierunkową. Na rok 2026 nie istnieją praktyczne ataki preimage ani kolizyjne na SHA-256. Najlepiej znany atak wymaga 2^128 operacji dla kolizji, co jest obliczeniowo niewykonalne przy obecnej i przewidywalnej technologii. SHA-256 jest zatwierdzony przez NIST i wykorzystywany w infrastrukturze krytycznej, w tym TLS, Bitcoinie i systemach federalnych.
Dlaczego niektóre systemy wciąż używają MD5, skoro jest złamany?
Główną przyczyną jest zgodność z systemami legacy. Wiele istniejących systemów, protokołów i formatów plików zaprojektowano wokół MD5, zanim odkryto jego słabości. Migracja wymaga skoordynowanych zmian we wszystkich komponentach. Dla zastosowań bez wymagań bezpieczeństwa, takich jak klucze cache i deduplikacja, przewaga szybkościowa MD5 i krótszy wynik czynią go pragmatycznym wyborem tam, gdzie ataki kolizyjne nie należą do modelu zagrożeń.