MD5 vs. SHA-1 vs. SHA-256: Welchen Hash sollten Sie verwenden?
Nehmen Sie SHA-256 für alles, was mit Sicherheit zu tun hat; MD5 und SHA-1 sind nur dort vertretbar, wo niemand etwas davon hat, einen passenden Hash zu fälschen.
MD5, SHA-1 und SHA-256 erledigen alle dieselbe Aufgabe: Sie verwandeln eine Eingabe beliebiger Länge in einen kurzen Fingerabdruck fester Größe, den sogenannten Digest oder Hashwert. Dieselbe Eingabe ergibt immer denselben Digest, und die Änderung eines einzigen Bits verändert das gesamte Ergebnis. Die drei unterscheiden sich in der Länge des Digests, in der Geschwindigkeit und, am wichtigsten, darin, ob jemand gezielt zwei verschiedene Eingaben mit demselben Digest erzeugen kann. Bei MD5 und SHA-1 ist das öffentlich gelungen, bei SHA-256 nicht.
Die drei Algorithmen auf einen Blick
| MD5 | SHA-1 | SHA-256 | |
|---|---|---|---|
| Digest-Größe | 128 Bit, 32 Hex-Zeichen | 160 Bit, 40 Hex-Zeichen | 256 Bit, 64 Hex-Zeichen |
| Veröffentlicht | 1992 (RFC 1321) | 1995 (FIPS 180-1) | 2001, als Teil der SHA-2-Familie |
| Kollisionen | Praktisch machbar seit 2004 | Praktisch machbar seit 2017 | Kein bekannter Angriff |
| Eingabe zu einem gegebenen Digest finden | Kein praktischer Angriff | Kein praktischer Angriff | Kein praktischer Angriff |
| Heute geeignet für | Prüfsummen ohne Sicherheitsbezug, Cache-Schlüssel | Nur Kompatibilität mit Altsystemen | Die Standardwahl für neue Projekte |
Hier die vollständigen Digests der fünf Bytes hello, wie sie md5sum, sha1sum und sha256sum ausgeben. Der Hash-Generator zeigt dieselben Werte nebeneinander, dazu SHA-384 und SHA-512, für Text oder für eine Datei bis 50 MB.
MD5 5d41402abc4b2a76b9719d911017c592
SHA-1 aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d
SHA-256 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
Was die zusätzlichen Bits bringen
Die Länge des Digests bestimmt den Aufwand eines generischen Angriffs, also eines Angriffs, der die Funktion als Blackbox behandelt. Wegen des Geburtstagsparadoxons braucht es bei einem n-Bit-Digest etwa 2^(n/2) Versuche, um irgendein Paar kollidierender Eingaben zu finden: 2^64 bei MD5, 2^80 bei SHA-1 und 2^128 bei SHA-256. Eine Eingabe zu finden, die zu einem bestimmten Digest passt (ein Urbild), kostet etwa 2^n Versuche.
Diese Zahlen gelten nur, solange das Design keine Abkürzung hat. MD5 und SHA-1 haben beide Abkürzungen für Kollisionen, deshalb sagt ihre Länge nicht mehr alles aus. Für SHA-256 ist keine Abkürzung bekannt, und 2^128 liegt weit jenseits jeder existierenden Rechenleistung.
Wie MD5 und SHA-1 gebrochen wurden
Ein Kollisionsangriff erlaubt niemandem, einen Hash umzukehren. Er erlaubt es einem Angreifer, vorab zwei verschiedene Eingaben mit demselben Digest vorzubereiten, eine davon als vertrauenswürdig durchzubringen und sie dann gegen die andere auszutauschen. Die gefährliche Variante ist eine Chosen-Prefix-Kollision: Der Angreifer wählt zwei sinnvolle Anfänge, etwa zwei Zertifikate mit unterschiedlichen Namen, und berechnet zusätzliche Bytes, die die Digests gleich machen.
- MD5, 2004: Xiaoyun Wang und Kollegen veröffentlichten praktisch durchführbare MD5-Kollisionen.
- MD5, 2008: Ein Forscherteam nutzte eine Chosen-Prefix-Kollision für MD5, um ein gefälschtes Zertifikat einer Zertifizierungsstelle zu erstellen, dem Browser vertraut hätten, weil eine kommerzielle CA Zertifikate noch mit MD5 signierte.
- MD5, 2012: Die Schadsoftware Flame nutzte eine MD5-Kollision, um ein Code-Signing-Zertifikat von Microsoft zu fälschen.
- SHA-1, 2017: Google und das CWI Amsterdam stellten SHAttered vor, zwei verschiedene PDF-Dateien mit demselben SHA-1-Digest. Das Team gab einen Rechenaufwand von etwa 6.500 CPU-Jahren und 110 GPU-Jahren an.
- SHA-1, 2020: Gaëtan Leurent und Thomas Peyrin veröffentlichten eine praktisch durchführbare Chosen-Prefix-Kollision für SHA-1 und nutzten sie, um sich als Inhaber eines PGP-Schlüssels auszugeben.
Browser akzeptieren seit 2017 keine TLS-Zertifikate mit SHA-1 mehr, und das NIST kündigte im Dezember 2022 an, SHA-1 solle bis Ende 2030 vollständig auslaufen. Weder für MD5 noch für SHA-1 gibt es einen praktischen Urbildangriff: Wer nur einen Digest kennt, kann keine Eingabe finden, die ihn erzeugt. Deshalb taugen beide weiterhin, um versehentliche Beschädigungen zu erkennen.
Geschwindigkeit: gemessen, nicht vermutet
MD5 gilt oft als der schnelle Algorithmus. Wir haben dieselben 256 MB Zufallsdaten mit Node 24 (OpenSSL 3.5) auf einem Desktop-Rechner gehasht, jeweils drei Durchläufe:
| Algorithmus | Durchsatz auf diesem Rechner |
|---|---|
| SHA-1 | etwa 1.000 MB/s |
| MD5 | etwa 730 MB/s |
| SHA-512 | etwa 690 MB/s |
| SHA-256 | etwa 460 MB/s |
Die Reihenfolge hängt vom Prozessor ab. Diese CPU hat keine SHA-Befehlssatzerweiterungen; Prozessoren mit diesen Erweiterungen beschleunigen SHA-1 und SHA-256 in Hardware, und dann kann SHA-256 schneller sein als MD5. SHA-512 war hier schneller als SHA-256, weil es mit 64-Bit-Wörtern arbeitet. Bei kurzen Eingaben verschwindet der Unterschied: Eine Million Hashes einer kurzen E-Mail-Adresse dauerten mit MD5, SHA-1 und SHA-256 jeweils zwischen 1,8 und 2,1 Sekunden, weil der Aufwand pro Aufruf das eigentliche Hashen überwiegt. Geschwindigkeit ist so gut wie nie ein echter Grund, sich für MD5 zu entscheiden.
Wofür jeder Algorithmus noch taugt
- MD5: versehentliche Beschädigungen erkennen, eigene Dateien deduplizieren, Cache-Schlüssel und ETags, und die Kommunikation mit Altsystemen, die MD5 erwarten. Niemals für Signaturen, Zertifikate oder Integritätsprüfungen, bei denen ein Angreifer die Datei liefern könnte.
- SHA-1: bestehende Systeme, die Sie noch nicht ändern können. Git benennt Objekte seit Langem mit SHA-1, verwendet dabei eine gehärtete Implementierung, die bekannte Kollisionsangriffe erkennt, und unterstützt außerdem Repositorys mit SHA-256. HMAC-SHA1, der Standardalgorithmus hinter TOTP-Codes aus Authenticator-Apps, ist von Kollisionsangriffen nicht betroffen.
- SHA-256: Prüfsummen für Downloads, digitale Signaturen, Zertifikate, HMAC, inhaltsadressierte Speicherung und alles Neue. Verwenden Sie SHA-256, wenn eine Prüfsumme Manipulationen standhalten muss, und behalten Sie MD5 für die Altwerte, mit denen Sie noch abgleichen müssen.
Sie wollen einen Download prüfen? Das Werkzeug Datei-Prüfsumme prüfen hasht die Datei lokal und sagt Ihnen, zu welchem Algorithmus eine eingefügte Prüfsumme passt.
Keiner davon gehört in die Passwortspeicherung
Alle drei sind auf Geschwindigkeit ausgelegt, und Geschwindigkeit ist genau das, was ein Angreifer will, der Milliarden Passwörter durchprobiert. Ein Salt verhindert vorberechnete Tabellen, verlangsamt das Raten aber nicht. Die Passwortspeicherung braucht eine Funktion, die absichtlich langsam ist und idealerweise viel Speicher benötigt (memory-hard). Auf demselben Rechner wie oben:
| Funktion und Einstellungen | Zeit pro Passwort |
|---|---|
| SHA-256, ein Aufruf aus Node | etwa 2,5 Mikrosekunden |
| Argon2id, 19 MiB Speicher, 2 Iterationen, 1 Lane | etwa 33 Millisekunden |
| PBKDF2-HMAC-SHA256, 600.000 Iterationen | etwa 270 Millisekunden |
| scrypt, N=2^17, r=8, p=1 | etwa 310 Millisekunden |
Diese Einstellungen sind die Mindestwerte aus dem OWASP Password Storage Cheat Sheet. Es empfiehlt an erster Stelle Argon2id, danach scrypt, für Altsysteme bcrypt mit einem Work Factor von 10 oder mehr und PBKDF2, wo FIPS-140-Konformität verlangt ist. Verwenden Sie die Passwort-Hashing-API Ihres Frameworks, statt selbst etwas aus einem einfachen Hash zusammenzubauen.
HMAC: wenn ein Hash einen Schlüssel braucht
Um nachzuweisen, dass eine Nachricht von jemandem stammt, der ein Geheimnis kennt, berechnen Sie nicht sha256(secret + message). MD5, SHA-1 und SHA-256 sind alle anfällig für Length-Extension-Angriffe: Wer den Digest einer Nachricht kennt, kann ohne Kenntnis des Geheimnisses einen gültigen Digest für dieselbe Nachricht mit angehängten Daten berechnen. HMAC (RFC 2104) verhindert das. HMAC-SHA256 ist die Standardwahl, und alle folgenden Aufrufe geben denselben Wert aus:
// Node.js
crypto.createHmac('sha256', 'secret').update('hello').digest('hex')
# Python
hmac.new(b'secret', b'hello', hashlib.sha256).hexdigest()
// PHP
hash_hmac('sha256', 'hello', 'secret')
// 88aab3ede8d3adf94d26ab90d3bafd4a2083070c3bcce9c014ee04a443847c0b
Vergleichen Sie HMACs mit einer Funktion, die in konstanter Zeit arbeitet, etwa crypto.timingSafeEqual, hmac.compare_digest oder hash_equals, und nicht mit ==.
Hashen auf der Kommandozeile und im Code
# Linux (coreutils)
md5sum file.iso
sha1sum file.iso
sha256sum file.iso
# macOS
md5 file.iso
shasum -a 1 file.iso
shasum -a 256 file.iso
# Windows PowerShell
Get-FileHash file.iso -Algorithm MD5
Get-FileHash file.iso -Algorithm SHA1
Get-FileHash file.iso # SHA256 is the default
# Any system with OpenSSL
openssl dgst -sha256 file.iso
# Hashing a string: printf adds no newline, echo does
printf '%s' hello | sha256sum # 2cf24dba5fb0a30e...
echo hello | sha256sum # 5891b5b522d5df08...
Im Browser unterstützt crypto.subtle.digest() SHA-1, SHA-256, SHA-384 und SHA-512, aber kein MD5; wer MD5 anfordert, bekommt einen NotSupportedError. Deshalb berechnen Browser-Werkzeuge, auch die auf dieser Website, MD5 mit einer separaten JavaScript-Implementierung.