Sie haben eine Festplatte mit tausenden von Dateien. Sie möchten heute für jede einzelne einen
Fingerprint festhalten, damit Sie in Monaten oder Jahren nachweisen können, dass sich nichts
verändert hat. Welchen der 586 Algorithmen von Jacksum wählen Sie?
Diese Anleitung geht darum, diese Entscheidung bewusst zu treffen und nicht aus Gewohnheit. Sie
erklärt die notwendigen Begriffe (Hashfunktion, CRC, Lawineneffekt, Kollisionsresistenz, was
"gebrochen" bedeutet), sie benennt die Algorithmen, die Sie nicht mehr einsetzen sollten, und sie
zeigt, wie Sie Jacksum dazu bringen, Ihnen das Nötige selbst zu sagen, anstatt einer Tabelle in
einem Blogartikel zu vertrauen.
Die Kurzantwort, falls Sie nur einen Absatz lesen:
| Situation | Wahl |
|---|---|
| Ein Angreifer ist möglich, und andere Werkzeuge müssen die Liste prüfen können | sha-256 |
| Ein Angreifer ist möglich, und Jacksum läuft auf beiden Seiten | sha3-256 |
| Langzeitarchiv, die Daten überleben den Algorithmus | sha256+sha3-256 |
| Sie möchten mehr Reserve als 256 Bit | sha-512/256 oder sha-512 |
| Die Prüfliste selbst liegt dort, wo ein Angreifer sie erreichen könnte | hmac:sha256 mit -k |
| Nur zufällige Verfälschung zählt, oder ein Protokoll gibt den Wert vor | crc32c, crc64_nvme |
Alles nach dieser Tabelle ist die Begründung — damit Sie die Wahl verteidigen, bei anderen
Randbedingungen anpassen und erkennen können, wann der Rat anderer veraltet ist.
Zwei Dinge tut diese Anleitung bewusst nicht. Sie ordnet Algorithmen nicht nach einer einzigen
"Stärke" ein, denn die richtige Wahl hängt von Ihrem Bedrohungsmodell ab und davon, wer das
Ergebnis prüfen muss. Und sie verlangt nicht, dass Sie ihren Zahlen glauben: jeder hier genannte
Wert lässt sich mit dem daneben stehenden Jacksum-Kommando reproduzieren.
Siehe auch
Eine Handvoll Begriffe trägt die gesamte Argumentation. Es lohnt sich, sie genau festzulegen,
denn die meisten schlechten Algorithmus-Entscheidungen entstehen daraus, dass zwei davon
vermischt werden.
Nachricht. Die Eingabe. Für unsere Zwecke die Bytes einer Datei. Jacksum kann auch
Zeichenketten, stdin, Datenträger und NTFS-Alternate-Data-Streams hashen; die Überlegungen sind
dieselben.
Hashfunktion. Eine Funktion, die eine Nachricht beliebiger Länge auf einen Wert fester Länge
abbildet. "Beliebige Länge" und "feste Länge" zusammen sind der Grund dafür, dass die
interessanten Eigenschaften überhaupt möglich und die Probleme unvermeidbar sind: es gibt
unendlich viele Nachrichten und nur endlich viele Ausgaben.
Hashwert. Die Ausgabe. Je nach Tradition auch Digest, Fingerprint, Prüfsumme oder
Prüfwert. Jacksum verwendet durchgehend "Hashwert" und kann ihn mit -E in 17 Kodierungen
ausgeben (Hex, Base32, Base64, BubbleBabble, z-base-32, dezimal und weitere).
Kollision. Zwei verschiedene Nachrichten mit demselben Hashwert. Kollisionen existieren
immer — das Schubfachprinzip garantiert es. Die Frage ist nur, ob jemand eine finden kann.
Kollisionsresistenz. Es soll praktisch unmöglich sein, irgendein Paar kollidierender
Nachrichten zu finden. Der Angreifer darf beide Nachrichten wählen, und genau das macht diese
Eigenschaft zur am leichtesten brechbaren der drei.
Urbildresistenz (Preimage). Zu einem gegebenen Hashwert soll es praktisch unmöglich sein,
eine Nachricht zu finden, die ihn erzeugt. Das ist die Bedeutung von "Einwegfunktion".
Zweite-Urbildresistenz (Second Preimage). Zu einer gegebenen Nachricht soll es praktisch
unmöglich sein, eine andere Nachricht mit demselben Hashwert zu finden. Das ist die für die
Dateiintegrität wichtigste Eigenschaft: der Angreifer hat Ihre Datei und will eine andere Datei,
die Ihre Prüfung besteht.
Blockgröße. Iterierte Hashfunktionen verarbeiten die Nachricht in Blöcken fester Größe.
Jacksum zeigt sie in --info unter Block size:. Sie ist für HMAC relevant, das verlangt, dass
die Blockgröße größer als die Ausgabegröße ist.
Merkle-Damgård-Konstruktion. Das klassische Design: die Nachricht in Blöcke zerlegen und
jeden Block zusammen mit dem laufenden Zustand in eine Kompressionsfunktion geben. MD5, SHA-1
und die gesamte SHA-2-Familie arbeiten so. Das ist einfach und gut verstanden, und es hat eine
strukturelle Eigenheit — siehe Length-Extension.
Schwamm-Konstruktion (Sponge). Das SHA-3-Design: die Nachricht in einen großen internen
Zustand absorbieren und die Ausgabe daraus herauspressen. Der Zustand ist größer als die Ausgabe,
was die Length-Extension-Eigenheit beseitigt und variable Ausgabelängen natürlich macht (genau
das ist eine XOF).
Hashbaum (Merkle-Baum). Die Blätter hashen, dann die Hashwerte hashen, bis zu einer einzigen
Wurzel. Jacksum bietet TTH und TTH2; BLAKE3 verwendet intern einen Baummodus. Bäume erlauben
Parallelität und teilweise Verifikation. Der Baummodus selbst führt keine Schwäche ein, das
Ergebnis ist also genau so stark wie die zugrunde liegende Hashfunktion.
CRC (Cyclic Redundancy Check). Keine Hashfunktion im kryptografischen Sinn, sondern der Rest
einer Polynomdivision über GF(2). Die Nachricht wird als Polynom aufgefasst und durch ein festes
Generatorpolynom geteilt; der Rest ist der CRC. Genau diese algebraische Struktur ist der
Grund, warum CRCs die Fehlermuster, für die sie entworfen wurden, hervorragend erkennen — und
genau der Grund, warum sie gegen einen Angreifer wertlos sind.
Rocksoft (tm) Model. Die Beschreibung mit sechs Parametern, die einen CRC vollständig
festlegt: Breite, Polynom, Anfangswert, ob Eingangs- und Ausgangsbits gespiegelt werden, und ein
finaler XOR-Wert. Jacksum implementiert es, sodass
-a crc:<width>,<poly>,<init>,<refIn>,<refOut>,<xorOut> jeden CRC reproduziert, dem Sie
begegnen. Zwei optionale Parameter gehen über das klassische Modell hinaus und mischen die
Nachrichtenlänge in den Wert. Siehe jacksum -h crc: und
algorithms.html.
Klassische Prüfsumme. Die Familie vor den CRCs: Bytes addieren (sum8 … sum64), sie
XOR-verknüpfen (xor8) oder eine etwas geschicktere Variante mit zwei laufenden Summen
(Adler-32, Fletcher). Billig — und, wie wir sehen werden, oft auf Weisen defekt, die auch ohne
Angreifer relevant sind.
Kryptografische Hashfunktion. Eine Hashfunktion, die zusätzlich Urbild-, Zweite-Urbild- und
Kollisionsresistenz gegen einen intelligenten Angreifer, der den Algorithmus kennt, zusichert.
Dieser letzte Teilsatz ist der ganze Unterschied zu einem CRC oder einer Prüfsumme, und Jacksum
hält ihn im Feld type: jeder Algorithmus-Dokumentation fest.
HMAC. Eine schlüsselbasierte Konstruktion auf einer Hashfunktion. Nicht der Hash von
Schlüssel und Nachricht aneinandergehängt, sondern ein bestimmtes verschachteltes Verfahren
(RFC 2104 / FIPS 198-1), dessen Sicherheit auf anderen Annahmen ruht als reines Hashen — weshalb
es einige gebrochene Hashfunktionen übersteht.
Eine gute Hashfunktion verhält sich wie eine Zufallsfunktion: kippt man ein Bit der Eingabe, soll
jedes Ausgabebit mit Wahrscheinlichkeit 1/2 und unabhängig kippen. Diese Eigenschaft heißt
Lawineneffekt (englisch avalanche effect, bzw. strict avalanche criterion), und der Zielwert
ist daher 50 % — nicht 100 %. Eine Funktion, bei der jedes Mal alle Ausgabebits kippen, wäre
genauso vorhersagbar wie eine, bei der keines kippt.
Jacksum misst das für Sie. --info --verbose details (bzw. -V details) gibt einen
Lawinen-Block aus:
$ jacksum -a sha-256 --info --verbose details
Avalanche effect:
input length in bytes: 9
input length in bits: 72
hash calculations: 73
input [hex]: 313233343536373839
input [bin]: 001100010011001000110011001101000011010100110110001101110011100000111001
avalanche min effect: 42.19 %
avalanche avg effect: 50.04 %
avalanche max effect: 57.03 %
Wie die Messung funktioniert. Jacksum hasht die Eingabe einmal als Referenz, kippt dann jedes
Eingabebit einzeln und hasht erneut — 72 Bit bedeuten 72 Kippvorgänge, also insgesamt 73
Hashberechnungen. Für jeden Kippvorgang wird die Hamming-Distanz zwischen dem neuen Hashwert und
der Referenz bestimmt, also wie viele Ausgabebits sich geändert haben, und als Prozentsatz der
Ausgabebreite ausgedrückt. Minimum, Mittelwert und Maximum dieser 72 Prozentwerte werden
ausgegeben. Die Standardeingabe ist die 9 Byte lange Zeichenkette 123456789; mit
-q <sequence> setzen Sie Ihre eigene ein:
$ jacksum -a sum32 --info -V details -q txt:"Hello World"
Wie man es liest. Der Mittelwert sollte nahe bei 50 % liegen. Genauso wichtig ist die
Streuung: ein Minimum von 42 % und ein Maximum von 57 % bedeuten, dass kein einzelnes
Eingabebit ungewöhnlich wenig oder ungewöhnlich viel Einfluss hat. Vergleichen Sie diese
gemessenen Werte:
| Algorithmus | min | avg | max | Urteil |
|---|---|---|---|---|
sha-256 |
42,19 % | 50,04 % | 57,03 % | lehrbuchmäßig |
sha3-256 |
42,58 % | 49,39 % | 54,69 % | lehrbuchmäßig, engste Streuung |
md5 |
39,84 % | 50,20 % | 61,72 % | lehrbuchmäßig (der Lawineneffekt war nicht MD5s Problem) |
crc32 |
34,38 % | 45,53 % | 62,50 % | für einen CRC respektabel |
adler32 |
6,25 % | 15,80 % | — | schlecht |
sum32 |
3,13 % | 7,07 % | 12,50 % | fast keine Diffusion |
elf |
3,13 % | 5,56 % | — | fast keine Diffusion |
xor8 |
12,50 % | 12,50 % | 12,50 % | überhaupt keine |
xor8 ist der perfekte Lehrfall: Minimum, Mittelwert und Maximum liegen alle bei exakt 12,50 %,
also 1/8. Das Kippen eines beliebigen Eingabebits kippt immer genau ein Ausgabebit. Es gibt keine
Diffusion — die Ausgabe ist eine lineare Funktion der Eingabe, und jedes Bit davon ist auf die
Bits zurückführbar, aus denen es kam.
Zwei Einschränkungen, beide wichtig.
Ein guter Lawinenwert ist notwendig, aber nicht ausreichend. CRC-32 erreicht respektable
45,53 % und ist dennoch trivial invertierbar: weil die Operation affin über GF(2) ist, kann
jeder einen Vier-Byte-Patch berechnen, der eine Datei auf einen beliebigen CRC-32-Wert zwingt.
MD5 hat einen prächtigen Lawineneffekt und ist vollständig gebrochen. Der Lawineneffekt ist ein
Design-Schnelltest — ein schlechter Wert beweist, dass die Funktion untauglich ist, ein guter
Wert beweist nichts über kryptografische Stärke.
Der Wert hängt von der Eingabelänge ab. Eine breite Funktion braucht genug Eingabe, um ihren
Zustand zu füllen. Der Standard-crc64 erreicht bei der 9 Byte langen Standardeingabe 6,47 %
und selbst bei 64 Byte nur 13,84 %, weil sein Generatorpolynom sehr dünn besetzt ist. Wenn Sie
Kandidaten vergleichen, geben Sie ihnen eine Eingabe, deren Größe Ihren echten Daten ähnelt:
$ jacksum -a crc64 --info -V details -q txt:"0123456789012345678901234567890123456789012345678901234567890123"
Die 586 Algorithmen von Jacksum verteilen sich auf drei Familien, die für drei verschiedene
Aufgaben entworfen wurden. Die Dokumentation jedes Algorithmus nennt die Familie im Feld type:
von jacksum -h <algo>.
| Klassische Prüfsumme | CRC | Kryptografische Hashfunktion | |
|---|---|---|---|
| Entworfen für | billiges Erkennen von Übertragungsfehlern | Erkennen der Fehlermuster eines physikalischen Kanals | Widerstand gegen einen intelligenten Angreifer |
| Typische Breite | 8–32 Bit | 8–64 Bit | 128–512 Bit |
| Erkennt | manche zufälligen Einzelbyte-Fehler | alle Bündelfehler bis zum Grad des Polynoms, beweisbar | jede Änderung, von jedem, mit überwältigender Wahrscheinlichkeit |
| Erkennt nicht | Umsortierung von Bytes, eingefügte Nullbytes, viele Mehrbyte-Fehler | absichtliche Veränderung | nichts Bekanntes, solange die Funktion hält |
| Kosten | trivial | sehr gering | gering bis moderat |
Jacksum-type: |
checksum |
CRC |
cryptographic hash function |
| Vom Angreifer invertierbar | ja | ja | nein |
Der Unterschied, der Ihre Wahl entscheidet, ist das Bedrohungsmodell, und es hat genau zwei
Fälle.
Fall 1: Zufälle. Ein Kabel verliert ein Bit, ein Plattensektor verrottet, RAM kippt ein Bit,
ein Download bricht ab. Solche Fehler sind zufällig und ohne Absicht. Ein 32-Bit-CRC fängt
praktisch alle davon: jeder einzelne Bündelfehler von bis zu 32 Bit wird mit Sicherheit erkannt,
und eine zufällige Verfälschung rutscht mit einer Wahrscheinlichkeit von etwa 2^-32 durch. Das
ist eine echte technische Garantie, und deshalb finden sich CRCs überall in der Hardware.
Fall 2: Ein Angreifer. Jemand will, dass Ihre Prüfung bei einer von ihm veränderten Datei
durchgeht. Jetzt ist der Fehler nicht zufällig — er ist gewählt, von jemandem, der die
Spezifikation des Algorithmus gelesen hat.
Gegen einen Angreifer bietet ein CRC nichts, und der Grund ist strukturell, nicht eine Frage der
Breite. Ein CRC ist eine affine Funktion über GF(2): crc(a XOR b) = crc(a) XOR crc(b) XOR c
für eine Konstante c. Daraus folgt, dass jeder eine veränderte Datei nehmen, die vier Bytes
berechnen kann, die angehängt oder eingesetzt werden müssen, und auf jedem beliebigen Ziel-CRC
landet. Von Rechenaufwand kann man dabei kaum sprechen; es ist das Lösen eines kleinen linearen
Gleichungssystems. Ein breiterer CRC hilft nicht, denn der Angriff sucht nicht — er löst.
Dasselbe gilt für sum, xor und Adler: die sind ebenfalls linear.
Das ist der folgenreichste Gedanke dieser Anleitung. Ein CRC beantwortet "haben sich die Daten
zufällig verändert?" Eine kryptografische Hashfunktion beantwortet "haben sich die Daten
überhaupt verändert?" Das sind verschiedene Fragen, und nur eine davon hat mit Sicherheit zu
tun.
Nichts davon macht CRCs obsolet. Sie sind aktuelle Technik, werden weiterhin in neue Standards
hineingeschrieben, und Jacksum dokumentiert, wo jeder einzelne verwendet wird. Es geht darum, sie
für die Aufgabe einzusetzen, die sie gut können.
Sie stehen in heutigen Spezifikationen, nicht nur in denen von gestern. Aus Jacksums eigener
Algorithmus-Dokumentation:
crc64_nvme — die NVM Express NVM Command Set Specification, Revision 1d, vom Dezembercrc32c — Castagnolis CRC-32, für iSCSI in RFC 7143 §13.1 spezifiziert und weit verbreitetcrc24 — die Prüfsumme im ASCII-Armor von OpenPGP (RFC 2440).crc8 — der System Management Bus (SMBus) und der Free Lossless Audio Codec (FLAC).crc32 — die Linie ISO 3309 / ITU-T V.42, die Ethernet, ZIP, gzip und PNG verwenden;crc32_bzip2 ist die Variante von bzip2 mit demselben Polynom.crc82_darc — der Data Radio Channel nach ETSI EN 300 751.cksum — POSIX 1003.2, weiterhin die Prüfsumme, die cksum(1) ausgibt.Warum sie diese Aufgaben weiterhin gewinnen. Ein CRC ist billig genug, um in wenigen Gattern
implementiert zu werden, und das zählt, wenn er in einem Plattencontroller oder einem Funkchip
laufen muss. Er ist schnell: crc32c ist der schnellste Algorithmus in Jacksums
Geschwindigkeitsrangliste. Und anders als eine Hashfunktion bringt er Beweise mit, welche
Fehlermuster er erkennt — eine Eigenschaft, die eine kryptografische Hashfunktion nicht bieten
kann, weil ihre Garantien probabilistisch und nicht kombinatorisch sind. Für einen 512-Byte-Sektor
oder einen Netzwerk-Frame ist ein CRC das richtige Werkzeug, und ein SHA-256 wäre überdimensioniert.
Dateisysteme. Jacksums Dokumentation vermerkt, dass SHA-256 optional von ZFS verwendet werden
kann, und dass ZFS' edonr-Prüfsumme ein Edon-R-512 ist, das mit einem poolspezifischen
Schlüssel gesalzen wird — die Werte von ZFS stimmen also absichtlich nicht mit den reinen
Edon-R-Werten überein, die Jacksum berechnet. (ZFS' Standardprüfsumme ist Fletcher-4, das Jacksum
nicht implementiert; verfügbar ist nur fletcher16.)
Einen beliebigen CRC nachbilden. Weil Jacksum das Rocksoft (tm) Model implementiert, können
Sie jeden CRC reproduzieren, den ein Gerät oder Protokoll vorgibt, und das Polynom in jeder
Darstellung betrachten:
$ jacksum -a crc:32,04C11DB7,FFFFFFFF,true,true,FFFFFFFF --info
$ jacksum -h crc:
--info gibt das Polynom in mathematischer, normaler, gespiegelter und Koopman-Notation aus,
dazu das reziproke Polynom — unschätzbar, wenn ein Datenblatt und eine Quelldatei sich zu
widersprechen scheinen. Siehe algorithms.html.
Die Regel. Verwenden Sie einen CRC, um Zufälle zu erkennen und um mit etwas
zusammenzuarbeiten, das einen vorschreibt. Verwenden Sie ihn nie als Sicherheitsmaßnahme und nie
als primären Fingerprint für eine große Dateisammlung — aus den Gründen in Stufe A.
Eine kryptografische Hashfunktion ist nicht einfach eine besser durchmischte Prüfsumme. Sie gibt
drei ausdrückliche Zusicherungen, und jede hat generische Angriffskosten, die kein Design
unterbieten kann — die Kosten für rohe Gewalt gegen eine ideale Funktion derselben Breite n:
| Eigenschaft | Was der Angreifer tun muss | Generische Kosten |
|---|---|---|
| Urbildresistenz | eine Nachricht zu einem gegebenen Hashwert finden | 2^n |
| Zweite-Urbildresistenz | eine andere Nachricht zum Hashwert einer gegebenen finden | 2^n |
| Kollisionsresistenz | irgendzwei kollidierende Nachrichten finden | 2^(n/2) |
Kollisionsresistenz kostet nur 2^(n/2) wegen des Geburtstagsparadoxons: der Angreifer zielt
nicht auf ein Ziel, sondern auf irgendeine Übereinstimmung unter vielen Kandidaten. Nachdem er
etwa √(2^n) Nachrichten gehasht hat, wird ein passendes Paar wahrscheinlich. Ein 256-Bit-Hash
bietet also 256 Bit Urbildresistenz, aber nur 128 Bit Kollisionsresistenz — und 128 Bit gilt
in der Branche als langfristige Untergrenze. Deshalb sind heute 256 Bit Ausgabe der Standard und
nicht 128.
Eine Unterscheidung, die meist übergangen wird und die die nötige Breite verändert.
Prüfung pro Datei. Sie haben pro Datei einen Hashwert festgehalten und vergleichen später neu
berechnete Werte damit. Hier gibt es keinen Geburtstagseffekt: jede Datei wird gegen ihren eigenen
gespeicherten Wert geprüft. Bei zufälliger Verfälschung liegt die Wahrscheinlichkeit einer
unerkannten Änderung bei etwa 2^-b, und sie verschlechtert sich nicht, wenn Dateien hinzukommen.
Gegen Zufälle bietet ein 32-Bit-Wert etwa eine unerkannte Verfälschung auf vier Milliarden — pro
Datei und unabhängig davon, wie viele Dateien Sie haben.
Identifikation über Dateien hinweg. Sie deduplizieren, suchen Duplikate oder gleichen eine
Wanted-Liste gegen einen ganzen Baum ab. Jetzt wird jede Datei mit jeder anderen
verglichen, die Geburtstagsschranke gilt für die gesamte Menge, und die Garantie verfällt mit
wachsender Sammlung. Hier brechen kurze Werte zusammen: siehe die Tabelle in Stufe A.
Derselbe 32-Bit-Wert kann also für die eine Aufgabe ausreichen und für die andere hoffnungslos
sein. Und sobald ein Angreifer hinzukommt, ändern sich beide Fälle: er wartet nicht auf einen
Zufall, er konstruiert einen.
Jacksum benennt die Familie im Feld type:, sodass Sie immer nachsehen können, womit Sie es zu
tun haben:
$ jacksum -h sha3-256 | head -20
In der Kryptografie gilt eine Funktion als gebrochen, wenn jemand einen Angriff veröffentlicht,
der die oben genannten generischen Kosten für mindestens eine der zugesicherten Eigenschaften
unterbietet. Beachten Sie, was das aussagt — und was nicht:
Jacksum verfolgt das pro Algorithmus und gibt es in einem Security:-Block aus. Es gibt fünf
Zustände (net.jacksum.algorithms.BrokenState):
| Zustand | Bedeutung |
|---|---|
no |
Gegen die vollständige Funktion ist kein Angriff besser als generisch bekannt |
partly |
Mindestens eine, aber nicht alle zugesicherten Eigenschaften sind gebrochen |
yes |
Die Funktion ist gebrochen |
depends |
Hängt von einem Parameter ab, z. B. der Hashfunktion unter einem HMAC |
n/a |
Die Frage stellt sich nicht — ein CRC oder eine Prüfsumme sichert nichts davon zu |
$ jacksum -a md5 --info --verbose details
Security:
broken: yes
yes, 2004: identical-prefix collisions can be computed in
seconds and chosen-prefix collisions in hours on a standard PC;
the attack has been demonstrated against real X.509
certificates (2008) and was abused by the Flame malware (2012);
the preimage resistance is not broken (best attack 2^123.4),
but MD5 must not be used for signatures
see also https://eprint.iacr.org/2004/199.pdf
Lesen Sie den Satz, nicht nur das Schlagwort. Ohne -V details erhalten Sie broken: yes und
nichts weiter; mit der Option bekommen Sie die Begründung, die Jahreszahlen und eine Primärquelle.
Der Unterschied zwischen "theoretisch geschwächt" und "Kollisionen in Sekunden auf einem Laptop"
steckt vollständig in diesem Text. Vier Beispiele, die man sich einprägen sollte:
md5 → yes. Identical-Prefix-Kollisionen in Sekunden, Chosen-Prefix-Kollisionen insha-1 → yes. Die erste Identical-Prefix-Kollision wurde im Februar 2017 berechnetsha-256 → no. "The best collision attacks reach 31 of 64 steps and are practical at thatsha3-256 → no. Die besten Kollisionsangriffe erreichen 5 von 24 Runden, die bestenTeilweise Brüche sind keine vollen Brüche. md2 ist partly gebrochen (die Urbildresistenz
der vollständigen Funktion fiel 2005), md4 dagegen yes (Kollisionen in einem Bruchteil einer
Sekunde). Beide gehören in Stufe C, aber es sind nicht dieselben Aussagen, und partly
für sicher zu halten ist ein eigenes Anti-Muster.
Eine Schwäche verdient eine eigene Behandlung, weil sie Funktionen betrifft, die nicht gebrochen
sind.
Jede Merkle-Damgård-Hashfunktion — MD5, SHA-1, die gesamte SHA-2-Familie — gibt ihren internen
Zustand in ihrer Ausgabe preis. Aus sha256(secret || message) und der Länge von secret kann
ein Angreifer, der secret nie erfährt, sha256(secret || message || padding || anything)
berechnen. Der Zustand am Ende Ihrer Nachricht ist genau das, was er zum Weiterhashen braucht.
Jacksum weist in SHA-256s eigener Sicherheitsnotiz darauf hin: "as a Merkle-Damgard construction it
permits length-extension attacks: use HMAC or sha-512/256 where that matters".
Drei Auswege, alle verfügbar:
hmac:sha256 — die HMAC-Konstruktion ist genau so entworfen, dass das nicht funktioniert.sha-512/256 — SHA-512 mit anderem Anfangswert, auf 256 Bit gekürzt. Jacksum: "thesha3-256 — ein Schwamm. Sein Zustand ist größer als seine Ausgabe, die Ausgabe verrät alsoFür den Dateiintegritäts-Anwendungsfall dieser Anleitung ist einfaches sha-256 auf einer Datei
hiervon nicht betroffen — Sie bauen ja kein H(secret || message). Relevant wird es in dem
Moment, in dem Sie etwas authentifizieren wollen, indem Sie ein Geheimnis voranstellen; und genau
diesen Fehler soll HMAC verhindern.
broken: no ist nur die halbe Wahrheit. Die andere Hälfte lautet: wie sehr hat es überhaupt
jemand versucht? Eine Funktion, die niemand untersucht hat, und eine, die hundert Kryptografen
ein Jahrzehnt lang angegriffen haben, melden beide "kein Angriff bekannt" — und das sind nicht
annähernd gleichwertige Aussagen.
Das ist die am meisten unterschätzte Dimension der Algorithmusauswahl, und sie lässt sich einfach
formulieren: "kein veröffentlichter Angriff" ist nur in dem Maß ein Indiz, in dem Aufmerksamkeit
aufgewendet wurde.
algorithms.html sortiert jeden
Algorithmus bereits nach seiner Herkunft. Als Prüfungsstufen gelesen, stärkste zuerst:
Stufe 1 — nationale und internationale Standards. Ein formales Normungsverfahren bedeutet
Jahre öffentlicher Begutachtung, eine offene Kommentierungsphase und institutionelle Verantwortung
danach. SHA-2 (NIST FIPS 180-4), SHA-3 und SHAKE (FIPS 202), Kupyna (Ukraine, DSTU 7564:2014),
Streebog (Russland, GOST R 34.11-2012), LSH (Republik Korea, KS X 3262), HAS-160 (KISA), SM3
(China), belt-hash (Belarus, STB 34.101.31), Whirlpool (ISO/IEC 10118-3).
Stufe 2 — Finalisten offener Wettbewerbe. Diese wurden konstruktionsbedingt hart
kryptanalysiert: viele unabhängige Teams, öffentliche Regeln und ein mehrjähriger Anreiz, die
Einreichungen der anderen zu brechen. Die fünf Finalisten der dritten SHA-3-Runde (BLAKE, Groestl,
JH, Keccak, Skein) und die fünf Finalisten des NIST-Wettbewerbs für Lightweight Cryptography, die
Hashen unterstützen (Ascon, Esch, PHOTON-Beetle, Romulus-H, Xoodyak). Ein Wettbewerb ist
wohl eine stärker adversarielle Prüfung als ein Normungsverfahren.
Stufe 3 — weit verbreitete Nicht-Standards mit starker unabhängiger Begutachtung. Kein
formaler Standard, aber intensive Praxisnutzung und dauerhafte Analyse durch Dritte: BLAKE2
(RFC 7693), BLAKE3, RIPEMD-160, Tiger und Tiger2.
Stufe 4 — Ausgeschiedene aus Wettbewerben. Kandidaten der Runden 1 und 2, die nicht
weiterkamen. Kandidat gewesen zu sein ist keine Empfehlung — mehrere wurden gerade deshalb
ausgeschieden, weil die Analyse Probleme fand. Unter denen, die Jacksum mitbringt, sind hamsi
und edonr heute als partly gebrochen markiert, und Fugue musste zu Fugue2 nachgebessert
werden. Es ist wertvoll, sie verfügbar zu haben; für ein Archiv sind sie keine Wahl.
Stufe 5 — Einzelvorschläge mit dünner Kryptanalyse. Die Gruppe der NIST-Workshops von 2005 vor
dem SHA-3-Wettbewerb ist das Lehrbuchbeispiel. Sie enthielt dha256, fork256 und vsh.
FORK-256 wurde 2007 gebrochen. VSH 2006 teilweise. DHA-256 hat keinen veröffentlichten Bruch —
aber angesichts dessen, was mit seinen beiden Weggefährten passierte, ist dieses saubere Zeugnis
ein schwaches Indiz und keine Empfehlung.
Die Fähigkeit, die es sich zu erwerben lohnt: Jacksums broken:-Text kodiert die Prüfungsdimension
ausdrücklich, nicht nur das Ja/Nein-Urteil. Vergleichen Sie:
$ jacksum -a dha256 --info -V details
"no, but boomerang attacks reach 46 of 64 steps and a pseudo-collision for the full function
is known (2^127.5); the full DHA-256 has no collision or preimage attack, but it has
received far less public analysis than SHA-256, which it was designed to improve upon"
$ jacksum -a belt-hash --info -V details
"no; no attack on belt-hash itself has been published; note however that the public
cryptanalysis of belt-hash is thin compared with SHA-2 or SHA-3: the third-party results
published so far target the underlying Bel-T block cipher and reach at most 6 of its 8 rounds"
$ jacksum -a groestl256 --info -V details
"no; Groestl was the most deeply analysed of the five SHA-3 finalists: the best collision
attacks on the hash function reach 3 of 10 rounds and the best distinguisher covers 9 of 10
rounds of the permutation (2^368, 2012), the full Groestl is unaffected"
Drei Algorithmen, alle broken: no, drei sehr unterschiedliche Vertrauensniveaus. Und Jacksum
sagt Ihnen auch, wenn eine standardisierte Funktion trotzdem zu kurz ist:
$ jacksum -a has160 --info -V details
"no, but the best collision attacks reach 53 of 80 steps (2^55) … the full HAS-160 is
unaffected, but its 160-bit output limits the collision resistance to 2^80, which is not
sufficient anymore; prefer at least 256 bits"
Die Regel. Für Daten, denen Sie in zehn Jahren noch vertrauen müssen, wählen Sie aus Stufe 1
oder 2 mit mindestens 256 Bit Ausgabe. Die Stufen 3 bis 5 sind interessant, manchmal
hervorragend und gelegentlich schneller — aber "keine bekannten Angriffe" auf ein unbekanntes
Design kann einfach bedeuten, dass niemand hingesehen hat.
Jacksum erlaubt es, beliebig viele Algorithmen mit + zu verketten:
$ jacksum -a sha256+sha3-256 -q txt:"Hello World"
$ jacksum -a sha256+crc32c --info
Das lohnt sich richtig zu verstehen, denn das naheliegende Argument dafür ist falsch und das
tatsächliche Argument ist stärker.
Jede Datei wird nur einmal gelesen, unabhängig davon, wie viele Algorithmen Sie wählen, und
die Algorithmen können in getrennten Threads laufen (--threads-hashing). Die Grenzkosten eines
zweiten Algorithmus sind also CPU und nicht I/O — und das ist für tausende Dateien auf einer
Platte nahezu kostenlos, weil I/O der Engpass ist. --info bestätigt, was Sie gebaut haben:
$ jacksum -a sha256+crc32c --info
Algorithm:
name: sha256+crc32c
actual combined algorithms: 2
Hash length:
bits: 288
Standardmäßig werden die Werte als eine zusammenhängende Zeichenkette ausgegeben. Für eine
Prüfliste möchten Sie sie wahrscheinlich getrennt haben, und das leistet -F mit indizierten
Tokens:
$ jacksum -a sha256+sha3-256 -F "#ALGONAME{i}: #HASH{i}" myfile
sha256: 222d5dc399137f3d9a9b74681e273430e3af626d4b9630966cd87e95d58af3c6
sha3-256: fafb96e583781353478913250870b1ee6029c39db298e6ae2e1fe4970eec2031
$ jacksum -a sha256+sha3-256 -F "#HASH{0} #HASH{1} #FILESIZE #FILENAME" -r max mydir
#HASH{<algo>} funktioniert ebenfalls, -F "#HASH{sha-256} #HASH{sha3-256} #FILENAME" ist also
gleichwertig und selbsterklärend. Algorithmen kombinieren geht seit Jacksum 1.7.0 (Juli 2006).
Die verlockende Überlegung lautet "256 Bit plus 256 Bit ergeben 512 Bit Sicherheit". Das ist
falsch.
Joux hat 2004 gezeigt (Multicollisions in Iterated Hash Functions, CRYPTO 2004), dass für zwei
iterierte Merkle-Damgård-Hashfunktionen mit n1 und n2 Bit eine Kollision für die Verkettung
H1(m) ‖ H2(m) etwa
(n2/2) · 2^(n1/2) + 2^(n2/2)
kostet und nicht 2^((n1+n2)/2). Das ist kaum mehr, als die stärkere der beiden allein
anzugreifen. Das Verfahren baut billig eine Multikollision — viele Nachrichten mit demselben
H1-Wert — indem es die iterierte Struktur ausnutzt, und sucht dann innerhalb dieser Menge eine
H2-Kollision. sha256+sha512 liefert also deutlich weniger, als seine 768 Bit Ausgabe
suggerieren.
Zwei Konsequenzen, nach denen man handeln sollte:
sha-512 oder sha-512/256; das ist günstiger und ehrlicher als Stapeln.sha256+sha3-256 kombiniert eine Merkle-Damgård-Funktion mit einem Schwamm;sha256+sha512 kombiniert zwei nahe Verwandte.Das eigentliche Argument ist technischer und nicht informationstheoretischer Natur: Verketten
ist eine Versicherung dagegen, dass der von Ihnen gewählte Algorithmus später gebrochen wird.
Sehen Sie sich an, wie Brüche tatsächlich abgelaufen sind. MD5 und SHA-1 fielen beide durch
Chosen-Prefix-Kollisionsangriffe — hochspezialisierte Konstruktionen um die
Differenzialstruktur einer Funktion herum, das Ergebnis jahrelanger gezielter Kryptanalyse genau
dieses Designs. Ein solcher Angriff erzeugt ein kollidierendes Paar für diese Funktion. Über
eine unabhängige zweite Funktion sagt er nichts und kann sie nicht gleichzeitig erfüllen. Niemand
hat je eine gleichzeitige Kollision für zwei unabhängige, strukturell verschiedene Hashfunktionen
vorgeführt.
Für das Szenario dieser Anleitung ist das sehr konkret. Nehmen Sie an, Sie versehen heute eine
Platte allein mit sha-256-Fingerprints. In zehn Jahren ist SHA-256 abgekündigt. Nun möchten Sie
das Vertrauen in das Archiv wiederherstellen — aber neu hashen erfordert, die Originaldaten zu
lesen, und bis dahin ist die Platte womöglich verschwunden oder bereits manipuliert. Ihre
Prüfliste ist genau in dem Moment unbrauchbar geworden, in dem Sie sie brauchten.
Wenn die Prüfliste zusätzlich sha3-256 festgehalten hat, haben Sie weiterhin einen
vertrauenswürdigen Fingerprint, ohne irgendetwas neu zu lesen. Das ist einen CPU-Thread wert.
Empfohlene Paarungen
| Paarung | Begründung |
|---|---|
sha256+sha3-256 |
Merkle-Damgård + Schwamm, verschiedene Entwicklerteams, beide Stufe 1. Die Standardwahl für Archive. |
sha256+blake3 |
Wenn die Geschwindigkeit späterer Prüfungen wichtiger ist als die Verfügbarkeit von Werkzeugen. |
sha-512/256+sha3-512 |
Maximale Reserve, beide immun gegen Length-Extension. |
Nicht als Sicherheitsmaßnahme empfohlen: eine kryptografische Hashfunktion plus ein CRC. Es
ist eine ansprechende Idee, und sie funktioniert nicht. Weil ein CRC affin ist, kann ein
Angreifer, der eine Hash-Kollision konstruiert hat, den CRC zusätzlich auf jeden gewünschten
Wert zwingen — es ist eine lineare Gleichung und keine Suche — der CRC trägt also überhaupt
keine Sicherheit gegen Angreifer bei. Ein CRC neben einem Hash bleibt als billiger Vorfilter für
zufällige Verfälschung nützlich, was eine echte, aber viel kleinere Aussage ist.
--info platziert jeden Algorithmus in einer Geschwindigkeitsrangliste:
$ jacksum -a sha-256 --info
Speed:
relative rank: 15/586
Rang 1 ist der schnellste. Die Rangliste stammt aus einer Gewichtstabelle im Quellcode
(net.jacksum.multicore.manyalgos.HashAlgorithm), wobei ein kleineres Gewicht schneller bedeutet:
| Algorithmus | Gewicht | Anmerkung |
|---|---|---|
crc32c |
4 | der schnellste in Jacksum |
crc32 |
5 | |
adler32 |
6 | |
sum32 |
10 | |
sha-1 |
11 | |
sha-256 |
11 | Rang 15/586 |
sha-512, sha-512/256 |
19 | |
sha3-256 |
32 | Rang 38/586 |
md5 |
35 | Rang 42/586 |
blake2b-256 |
43 | |
blake3 |
95 | Rang 468/586 |
Zwei Schlussfolgerungen, die beide verbreiteten Ratschlägen widersprechen.
SHA-256 ist schneller als MD5. Gewicht 11 gegen 35; Rang 15 gegen 42. Moderne CPUs haben
SHA-2-Befehle und das JDK nutzt sie, während MD5 keine solche Unterstützung erhält. "MD5 nehmen,
weil es schneller ist" war 1998 richtig und ist seit Jahren falsch. Es bleibt kein
Geschwindigkeitsargument dafür, eine gebrochene Funktion zu wählen.
Ein Rang ist eine Eigenschaft dieser Implementierung, nicht des Algorithmus. BLAKE3 ist eine
der schnellsten Hashfunktionen überhaupt — in optimiertem C mit SIMD. In Jacksums
Java-Implementierung belegt es Rang 468 von 586. Der Algorithmus ist hervorragend; diese konkrete
Implementierung ist nicht schnell. Übertragen Sie Benchmark-Zahlen niemals zwischen
Implementierungen.
Und meist ist all das ohne Bedeutung. Bei tausenden Dateien auf einer Platte ist der Engpass
I/O und nicht Arithmetik. SHA-256 läuft mit Gigabyte pro Sekunde; eine drehende Platte liefert
das nicht. Was tatsächlich etwas bewegt:
$ jacksum -a sha-256 --threads-reading max -r max mydir # parallele Lesevorgänge, gut für SSD/NVMe
$ jacksum -a sha256+sha3-256 --threads-hashing 2 -r max mydir # beide Hashes, ein Lesedurchgang
Weil -a a+b jede Datei einmal liest, kostet ein zweiter Algorithmus nur CPU — siehe
Verketten.
Messen Sie auf Ihrer eigenen Hardware, statt irgendeiner Tabelle zu glauben, auch dieser
nicht:
$ for a in crc32c sha-256 sha3-256 blake3 whirlpool; do
> printf '%-12s' "$a"; /usr/bin/time -p jacksum -a $a bigfile.bin 2>&1 | awk '/real/{print $2" s"}'
> done
Verwenden Sie eine Datei, die groß genug ist, dass der JVM-Start (etwa 50 ms) im Rauschen
verschwindet — mindestens einige hundert MB.
Für 28 Algorithmen kann Jacksum denselben Hashwert auf zwei verschiedenen Wegen berechnen. Das ist
für die Performance wissenswert, und für das Vertrauen noch wertvoller.
Standardmäßig verwendet Jacksum die Implementierung, die das Java-API bereitstellt —
java.security.MessageDigest, java.util.zip.CRC32 und so weiter — weil JVM-Hersteller diese
stark optimieren und häufig auf CPU-Intrinsics oder nativen Code abbilden. Die Option -A
schaltet auf Jacksums eigene reine Java-Implementierung um, sofern es eine gibt. Laut
jacksum -h haben diese Algorithmen eine Alternative:
adler32, blake3, crc16, crc32, crc32_fddi, crc32c, fnv-0_32, fnv-0_64, fnv-1_32,
fnv-1_64, fnv-1a_32, fnv-1a_64, fugue224, fugue256, fugue384, fugue512, md2, md5,
sha-1, sha-256, sha-384, sha-512, sha-512/224, sha-512/256, sha3-224, sha3-256,
sha3-384, sha3-512
Für jeden anderen Algorithmus wird -A ignoriert. --info zeigt, welche aktiv ist:
$ jacksum -A -a sha-256 --info
Speed:
relative rank: unknown, speed is calculated for primary algorithms only
Alternative/secondary implementation:
has been requested: true
is available and would be used: true
Welche Implementierung Sie standardmäßig bekommen, ist ein Detail Ihres JRE-Herstellers und
dessen Version und kann sich zwischen Releases ändern. Der praktische Rat ist unverändert
gegenüber dem Tag, an dem diese Option eingeführt wurde: verwenden Sie ein aktuelles JRE und
nehmen Sie die Performance, die es bietet. Eine Messung auf einer Maschine (JDK 25, aarch64,
47 MB Datei):
| Implementierung | Laufzeit |
|---|---|
| Standard (JDK) | 0,10 s |
-A (reines Java) |
0,19 s |
Beide Werte enthalten etwa 50 ms JVM-Start, das Hashen selbst unterscheidet sich also stärker, als
das Verhältnis vermuten lässt. Betrachten Sie das als einen Datenpunkt, nicht als Gesetz — auf
einer anderen JVM oder Architektur ist der Abstand anders, und gelegentlich gewinnt der reine
Java-Pfad.
Ein Hashwert ist nur so vertrauenswürdig wie der Code, der ihn erzeugt hat. Sie sind gerade dabei,
eine ganze Platte mit Fingerprints zu versehen und sich jahrelang auf diese Werte zu verlassen;
ein Implementierungsfehler würde viel zu spät entdeckt. Zwei unabhängige Implementierungen, die
sich bei einem bekannten Testvektor einig sind, sind ein echtes Indiz — und -A macht daraus
einen Einzeiler:
$ jacksum -a sha-256 -q txt:"abc"
ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad
$ jacksum -A -a sha-256 -q txt:"abc"
ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad
Dieser Wert ist gleichzeitig der von NIST veröffentlichte Testvektor für SHA-256 von "abc".
Nehmen Sie eine dritte, völlig unabhängige Implementierung aus der
Kompatibilitätsliste hinzu:
$ printf 'abc' | sha256sum
ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad -
Drei unabhängige Codepfade, ein Wert, übereinstimmend mit dem Testvektor des Standards selbst.
Führen Sie das einmal aus, bevor Sie ein Archiv einem Algorithmus anvertrauen, und die Korrektheit
der Implementierung ist keine Sorge mehr.
Jacksum ist reines Java, alle 586 Algorithmen stehen Ihnen also auf jeder Plattform zur Verfügung,
auf der Java läuft. Dadurch vergisst man leicht die Einschränkung, die tatsächlich weh tut:
Die Frage ist nicht "kann ich diesen Hash berechnen?", sondern "kann derjenige, der ihn
später prüft, ihn mit den Werkzeugen berechnen, die er dann hat?"
Eine Prüfliste ist eine Nachricht an die Zukunft. Wenn die lesende Person nur sha256sum hat oder
nur certutil von Windows, dann ist eine BLAKE3-Liste ein toter Brief, so gut BLAKE3 auch ist.
Genau dafür ist der Block compatibility: von jacksum -h <algo> da. Er nennt pro Algorithmus
den Aufruf für Dutzende von Betriebssystemen, Werkzeugen und Programmiersprachen:
$ jacksum -h sha-256
compatibility:
- 7z: 7z h -scrcsha256
- BusyBox: /bin/sha256sum
- FreeBSD 6+: /sbin/sha256
- GNU/Linux: /usr/bin/sha256sum
- gpg: gpg --print-md sha256
- macOS 10.12+: /usr/bin/shasum -a 256
- OpenSSL: openssl dgst -sha256
- PowerShell: Get-FileHash -Algorithm SHA256
- Python 2.5+: hashlib.sha256()
- Solaris 10+: /usr/bin/digest -a sha256
- Windows 7+: certutil -hashfile <file> SHA256
Verdichtet für die Kandidaten, die Sie wahrscheinlich erwägen (● natives Werkzeug vorhanden,
○ keines):
| GNU/Linux | macOS | Windows | FreeBSD | Solaris | BusyBox | OpenSSL | 7-Zip | gpg | Python | Java | Go | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
sha-256 |
● | ● | ● | ● | ● | ● | ● | ● | ● | ● | ● | ● |
sha-512 |
● | ● | ● | ● | ● | ● | ● | ○ | ● | ● | ● | ● |
sha-512/256 |
● | ● | ○ | ● | ● | ○ | ● | ○ | ○ | ○ | ● | ● |
sha3-256 |
○ | ○ | ○ | ○ | ● | ● | ● | ● | ○ | ● | ● | ● |
blake2b-256 |
● | ○ | ○ | ○ | ○ | ○ | ● | ○ | ○ | ● | ○ | ● |
blake3 |
○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ |
md5 |
● | ● | ● | ● | ● | ● | ● | ● | ○ | ● | ● | ○ |
crc32 |
○ | ● | ○ | ● | ○ | ○ | ○ | ● | ○ | ● | ● | ● |
Lesen Sie die Zeilen genau, denn die Ergebnisse entsprechen nicht dem Ruf der Algorithmen:
sha-256 ist der einzige Algorithmus mit wirklich universeller Unterstützung. Jedessha3-256 hat kein natives Werkzeug auf GNU/Linux, macOS, Windows oder FreeBSD. Es ist einsha-512/256 hat unter Windows nichts. shasum -a 512256 deckt Linux und macOS ab,/sbin/sha512t256, Solaris 11.4+ hat digest -a 512_t -t 256. Windows hat wedercertutil- noch PowerShell-Unterstützung.blake3 hat überhaupt keinen Eintrag. In der Praxis ist es Jacksum-only. Einemd5 und crc32 sind am breitesten verfügbar, und genau deshalb werden sie immer wiederDie daraus folgenden Regeln
-h <algo>, statt es anzunehmen.--style: gnu-linux, bsd,bsd-r, solaris-digest, fciv, openssl-dgst, sfv und weitere. jacksum -hJacksum bringt 586 Algorithmen mit, weil es ein umfassendes Framework ist: es muss eine 1998
erzeugte Prüfliste lesen, den CRC eines Geräts nachbilden und historische Funktionen zu
Lehrzwecken vorführen können. Verfügbarkeit in Jacksum ist ausdrücklich keine Empfehlung.
Für das Fingerprinting einer großen Dateisammlung sollte Folgendes nicht auf Ihrer Liste stehen.
Die Gruppierung erfolgt nach dem Warum, denn die Gründe sind völlig verschieden und die
Gegenmaßnahme unterscheidet sich ebenfalls.
Die Ausgabebreite begrenzt die Kollisionsresistenz, ganz gleich wie gut das Design ist. Jacksum
hat 9 Algorithmen mit 8 Bit Ausgabe, 14 mit 16 Bit und 8 mit 24 Bit:
$ jacksum -a all:8 -l
blake2b-8 blake2s-8 crc8 md6-8 skein-256-8 skein-512-8 skein-1024-8 sum8 xor8
Unter der Annahme einer idealen, gleichverteilten Funktion genügen etwa 1,1774 · √(2^b)
Elemente für eine 50-prozentige Chance, dass irgendein Paar kollidiert:
| Breite | 50 % Chance auf eine Kollision | Kollision garantiert (Schubfachprinzip) | Beispiele |
|---|---|---|---|
| 8 Bit | ~19 Dateien | 257 Dateien | sum8, xor8, crc8, blake2b-8 |
| 16 Bit | ~301 Dateien | 65 537 Dateien | sum16, sum_bsd, sum_sysv, crc16, fcs16, fletcher16 |
| 24 Bit | ~4 800 Dateien | 16 777 217 Dateien | sum24, crc24 |
| 32 Bit | ~77 000 Dateien | 2^32 + 1 Dateien | crc32, adler32, xxh32, elf |
| 64 Bit | ~5,1 · 10^9 Dateien | — | crc64_xz, sum64 |
| 128 Bit | ~2,2 · 10^19 Dateien | — | md5, ripemd128, tiger128 |
| 256 Bit | ~4 · 10^38 Dateien | — | sha-256, sha3-256, blake3 |
Für "tausende Dateien auf einer Platte" sind die Zeilen mit 8, 16 und 24 Bit einfach
disqualifiziert: bereits ein paar hundert Dateien kollidieren. Die 32-Bit-Zeile übersteht die
Prüfung pro Datei, versagt aber bei der Identifikation über Dateien hinweg — bei 77 000
Dateien stehen die Chancen 50:50, dass ein gemeldetes Duplikat keines ist. Siehe die
Unterscheidung.
Gutes Design kann fehlende Breite nicht zurückkaufen. Das ist der lehrreichste Fall dieser
ganzen Anleitung:
$ jacksum -a blake2b-8 --info -V details
BLAKE2b, auf 8 Bit gekürzt, erreicht einen lehrbuchmäßigen mittleren Lawineneffekt von 51,91 %
— besser als die 50,04 % von SHA-256. Es leitet sich von einer hervorragenden, gut begutachteten
Funktion ab. Und es ist für eine Platte voller Dateien völlig unbrauchbar, denn 8 Bit sind 8 Bit:
256 mögliche Werte, also müssen 257 Dateien kollidieren. Ein perfekter Lawineneffekt in einem
winzigen Ausgaberaum bleibt ein winziger Ausgaberaum.
Dieselbe Rechnung setzt mehrere Funktionen außer Dienst, die nicht gebrochen sind:
| Algorithmus | broken: |
Warum trotzdem meiden |
|---|---|---|
has160 |
no |
160 Bit → 2^80 Kollisionsresistenz. Jacksum: "not sufficient anymore; prefer at least 256 bits" |
ripemd128 |
no |
128 Bit → 2^64. Außerdem Landelle/Peyrin 2013: Kollision für die vollständige Kompressionsfunktion und ein Distinguisher für die vollständige Hashfunktion |
tiger128, tiger160 |
no |
Kürzungen von Tiger-192 → 2^64. Jacksum: "the truncation itself is not a weakness" — die Breite ist es |
md6-16, skein-512-32, … |
no |
gute Funktionen, auf eine unbrauchbare Breite konfiguriert |
Kürzen Sie nicht, um Platz zu sparen. Ein 32-Byte-Hash für eine Million Dateien sind 32 MB. Es
gibt kein Speicherplatzargument, das die Aufgabe von Kollisionsresistenz rechtfertigt.
Diese versagen sogar im Fall der zufälligen Verfälschung, also bei der Aufgabe, für die sie
nominell gebaut wurden. Jedes Versagen lässt sich in einer Zeile zeigen.
sum8 … sum64 — die Byte-Reihenfolge wird ignoriert, und Nullbytes verschwinden.
Jacksums eigene Dokumentation sagt es: der Algorithmus "does not consider the order of the bytes in
the data stream. And since the algorithm only adds up the values of the bytes, all zero bytes are
ignored." Sehen Sie:
$ jacksum -a sum32 -q txt:"abc"
294 3
$ jacksum -a sum32 -q txt:"cba"
294 3
$ jacksum -a sum32 -q txt:"bca"
294 3
Jede Permutation der Bytes einer Datei erzeugt denselben Wert. Datensätze in einer Datei
umsortieren, zwei Felder tauschen, einen Block umdrehen — alles unsichtbar. Und das Anhängen von
Nullbytes ändert ebenfalls nichts:
$ jacksum -a sum32 -q hex:616263
294 3
$ jacksum -a sum32 -q hex:61626300000000
294 7
Die Prüfsumme bleibt 294; nur das Größenfeld wandert von 3 auf 7.
xor8 — doppelte Bytes heben sich auf.
$ jacksum -a xor8 -q txt:"abc"
96 3
$ jacksum -a xor8 -q txt:"abcxx"
96 5
Da x XOR x = 0 gilt, trägt jedes Byte, das eine gerade Anzahl von Male vorkommt, nichts bei.
Zusammen mit dem konstanten Lawineneffekt von 12,50 % erkennt xor8 fast nichts.
elf — ein Symboltabellen-Hash, keine Prüfsumme. Mittlerer Lawineneffekt 5,56 %, Minimum
3,13 %. Er wurde entworfen, um Namen in der Hashtabelle des ELF-Objektformats zu verteilen, und
darin ist er gut.
sum_bsd, sum_sysv, sum_minix, cksum (Minix) — 16-Bit-Varianten von sum(1), die nur
existieren, damit Jacksum reproduzieren kann, was historische Unix-Werkzeuge ausgaben.
prng, strsum, joaat, fnv-* — nicht-kryptografische Hashfunktionen für Hashtabellen.
Schnell und für diesen Zweck gut verteilt; prng und strsum zeigen Lawinen-Minima von 3,13 %.
Im Gegensatz dazu verhalten sich die Algorithmen, die sehr wohl auf die Reihenfolge achten, wie
erhofft:
$ jacksum -a adler32 -q txt:"abc" → 38600999 3 $ jacksum -a adler32 -q txt:"cba" → 38863143 3
$ jacksum -a crc32 -q txt:"abc" → 891568578 3 $ jacksum -a crc32 -q txt:"cba" → 3635344512 3
$ jacksum -a sha-256 -q txt:"abc" → ba7816bf… $ jacksum -a sha-256 -q txt:"cba" → 6d970874…
Ein abmilderndes Detail, das man kennen sollte. Jacksums Standardausgabe und der Stil full
halten die Dateigröße neben dem Wert fest, was den Nullbyte-Trick von oben auffängt (294 3
gegenüber 294 7). Ein Größenfeld ist eine nützliche Zusatzsicherung und kein Ersatz für einen
echten Hash — gegen das Umsortieren von Bytes hilft es nicht, und ein Angreifer kontrolliert es so
leicht wie den Inhalt.
Meiden Sie das SFV-Format für alles, was zählt. Jacksum kann es schreiben, was nicht dasselbe
ist wie eine Empfehlung. Seine Definition
(src/main/resources/net/jacksum/compats/defs/sfv.properties) lautet:
algorithm.default=crc32
formatter.format=#FILENAME #CHECKSUM{hex-uppercase}
Nur CRC-32, und überhaupt keine Dateigröße — es verliert also sogar die schwache Sicherung von
oben.
Verwenden Sie diese nur, um eine alte Prüfliste zu lesen, nie um eine neue zu erzeugen. Jacksum
markiert 15 Algorithmen als yes oder partly gebrochen:
| Algorithmus | Zustand | Warum |
|---|---|---|
md5 |
yes |
Kollisionen in Sekunden (2004); X.509-Demonstration 2008; Flame 2012 |
sha-1 |
yes |
SHAttered 2017 (2^63,1); Chosen-Prefix Shambles 2020 (2^63,4, ≈45 000 USD) |
md4 |
yes |
Kollisionen in einem Bruchteil einer Sekunde |
md2 |
partly |
Urbildresistenz der vollständigen Funktion gebrochen (2005) |
sha0 |
yes |
Kollisionsresistenz der vollständigen Funktion gebrochen (2004) |
ed2k |
yes |
auf MD4 aufgebaut |
haval |
yes |
Kollisionen für die vollständige Funktion bei jeder Rundenzahl bekannt |
gost |
yes |
Kollisions- und Urbildresistenz gebrochen (2008) |
mdc2 |
yes |
die hier implementierte blockchiffrenbasierte Variante |
panama |
yes |
der Hash-Modus ist praktisch gebrochen (2007) |
fork256 |
yes |
Kollisionsresistenz der vollständigen Funktion gebrochen (2007) |
streebog512 |
partly |
Zweite-Urbildresistenz der vollständigen Funktion (2014) |
hamsi<n> |
partly |
Zweite-Urbildresistenz der vollständigen Funktion (2010) |
edonr<n> |
partly |
Urbildresistenz theoretisch gebrochen (2009); Secret-Prefix-MAC praktisch gebrochen |
vsh |
partly |
Urbildresistenz gebrochen (2006) |
md5 und sha-1 sind die beiden, die in der Praxis zählen, weil sie noch überall installiert
sind und noch von viel zu vielen Werkzeugen standardmäßig angeboten werden. Um es zu wiederholen:
"weit verbreitet" ist kein Argument, und wie der Abschnitt zur Geschwindigkeit
zeigt, ist MD5 nicht einmal mehr schnell.
Eine Falle, in die auch umsichtige Menschen tappen. "CRC-64" ist nicht ein Algorithmus, und die
Varianten sind nicht gleich gut:
| ID | Lawineneffekt avg (9-Byte-Eingabe) | Lawineneffekt avg (64-Byte-Eingabe) |
|---|---|---|
crc64 |
6,47 % | 13,84 % |
crc64_go-iso |
6,47 % | — |
crc64_ecma |
50,13 % | — |
crc64_xz |
50,13 % | — |
crc64 und crc64_go-iso verwenden das dünn besetzte Polynom x^64 + x^4 + x^3 + x + 1 (jenes,
das die Proteindatenbank SWISS-PROT bis 2009 verwendete — und das, wie
algorithms.html anmerkt, häufig fälschlich ISO 3309 zugeschrieben
wird). Mit nur fünf Termen diffundiert es sehr langsam. crc64_ecma und crc64_xz basieren auf
ECMA-182 und verhalten sich, wie sich ein 64-Bit-CRC verhalten sollte.
Der Name sagt also fast nichts, die Parameter dagegen alles. Sehen Sie immer nach:
$ jacksum -a crc64 --info -V details # Polynom, init, Spiegelung, xorOut, Lawineneffekt
$ jacksum -a crc64_xz --info -V details
Die abschließende Regel für diesen ganzen Abschnitt. Um tausende Dateien für eine spätere
Prüfung mit Fingerprints zu versehen, wählen Sie eine kryptografische Hashfunktion mit
mindestens 256 Bit, markiert als broken: no, aus Prüfungsstufe 1 oder 2. Alles in
Stufe A und Stufe B existiert für Formatkompatibilität, Alt-Interoperabilität,
Protokollkonformität und Lehre — und das ist der einzige Grund, warum Jacksum es anbietet.
Hier ein Ergebnis, das überrascht: HMAC-MD5 hat keinen praktikablen Angriff, obwohl MD5
vollständig gebrochen ist.
Das ist keine Lücke, sondern eine Folge dessen, was HMAC voraussetzt. Reines Hashen beruht auf
Kollisionsresistenz — der Eigenschaft, die MD5 2004 verlor. HMAC nicht. Sein Sicherheitsbeweis
ruht darauf, dass sich die Kompressionsfunktion unter einem geheimen Schlüssel wie eine
Pseudozufallsfunktion verhält, und ein Kollisionsangriff sagt darüber nichts. Obendrein kennt der
Angreifer den Schlüssel nicht, kann eine Kollision also nicht einmal auf den richtigen internen
Zustand ausrichten.
Jacksum sagt das selbst:
$ jacksum -a hmac:md5 -k txt:secret --info --verbose details
Security:
broken: depends
depends on the underlying hash function; note that a broken
hash function does not necessarily yield a broken HMAC:
HMAC-MD5 has no practical attack although MD5 itself is broken,
because the HMAC construction does not rely on collision
resistance; nevertheless HMAC should be instantiated with a
hash function that is not broken
HMAC parameters:
underlying cryptographic hash: md5
truncate to bits: no truncation
trunc. length should have min. bits: 80
key length should have min. bytes: 16
key length follows above recom.: false
key will be hashed: false
Beachten Sie die letzten vier Zeilen: Jacksum prüft Ihren Schlüssel und die Kürzung gegen die
Empfehlungen von RFC 2104 / FIPS 198-1 und sagt Ihnen, wenn sie zu kurz greifen.
key length follows above recom.: false bedeutet, dass der sechs Zeichen lange Schlüssel secret
unter den empfohlenen 16 Byte liegt.
"Kann" ist nicht "soll". Instanziieren Sie HMAC für alles Neue mit einer Funktion, die nicht
gebrochen ist. Dass hmac:md5 heute sicher ist, ist eine Aussage über den aktuellen Stand der
Kryptanalyse von MD5s Kompressionsfunktion und kein Versprechen. Es gibt keinen Vorteil, das
auszureizen: hmac:sha256 kostet dasselbe und steht auf viel festerem Grund.
Es gibt einen zweiten, davon unabhängigen Grund, warum eine gebrochene Hashfunktion manchmal
akzeptabel ist: wenn es überhaupt keinen Angreifer gibt. Deduplizierung im eigenen Speicher,
Cache-Schlüssel, "habe ich diese Datei schon gesehen" — bei diesen Aufgaben versucht niemand, eine
Kollision zu konstruieren, und MD5s 128 Bit Ausgabe und gute Verteilung erledigen die Arbeit. In
dem Moment, in dem der Wert eine Vertrauensgrenze überschreitet, löst sich diese Begründung auf.
Das ist der für unser Szenario entscheidende Teil, und er hat gar nichts mit gebrochenen
Algorithmen zu tun.
Eine einfache Hashliste schützt die Dateien. Sie schützt nicht sich selbst. Ein Angreifer, der
Ihre Dateien verändern kann, kann meist auch files.sha256 verändern — die Hashwerte der
manipulierten Dateien neu berechnen, in die Liste schreiben, und Ihre Prüfung läuft sauber durch.
Die Liste ist nur dann vertrauenswürdig, wenn ihre Integrität durch etwas außerhalb der Reichweite
des Angreifers garantiert wird.
Genau das leistet HMAC, mit einem Schlüssel, den der Angreifer nicht hat:
$ jacksum -a hmac:sha256 -k password --style full -o files.hmac -r max mydir
$ jacksum -a hmac:sha256 -k password --style full -c files.hmac
-k akzeptiert txt:, hex: und weitere Präfixe, oder wörtlich readline bzw. password, um
interaktiv zu fragen, statt den Schlüssel in Ihrer Shell-History zu hinterlassen. Ohne den
Schlüssel kann ein Angreifer keine Werte erzeugen, die die Prüfung bestehen, ganz gleich wie viel
des Dateisystems ihm gehört.
Alternativen, die dasselbe Ziel anders erreichen: die Liste auf einmalig beschreibbaren oder
schreibgeschützten Medien ablegen, sie auf einer getrennten vertrauenswürdigen Maschine halten
oder sie signieren (gpg --detach-sign files.sha256). Nehmen Sie, was zu Ihrem Aufbau passt —
aber nehmen Sie eines. Eine Hashliste auf demselben beschreibbaren Datenträger wie die Daten, die
sie schützt, ist ein Anti-Muster.
Umfang. 492 der 586 Algorithmen von Jacksum lassen sich mit HMAC verwenden:
$ jacksum --hmacs -V summary # die Liste und die Anzahl
$ jacksum --hmacs -V info # pro Algorithmus: Ausgabegröße, Blockgröße, empfohlene Mindestwerte
Die übrigen 94 sind ausgeschlossen, weil sie keine kryptografischen Hashfunktionen sind, oder weil
ihre Blockgröße ihre Ausgabegröße nicht übersteigt (was RFC 2104 verlangt — das schließt die
Schwamm- und XOF-Konstruktionen aus), oder weil sie keine einfachen iterierten Funktionen sind
(die Baummodi). Details in algorithms.html.
Fünf Fragen, in dieser Reihenfolge. Jede verkleinert das Feld, und keine davon fragt, welcher
Algorithmus am eindrucksvollsten klingt.
1. Ist ein Angreifer im Bedrohungsmodell?
Nicht "ist einer wahrscheinlich" — ist einer möglich. Könnte irgendjemand davon profitieren,
dass Ihre Prüfung bei veränderten Daten durchgeht? Wenn es um Software, Backups, Beweismittel,
juristische oder finanzielle Unterlagen oder überhaupt etwas geht, das Ihre Kontrolle verlässt,
lautet die Antwort ja. Lautet sie nein und bleibt sie nein, ist ein CRC wirklich ausreichend und
deutlich günstiger.
2. Wer prüft, und womit?
Wenn Jacksum auf beiden Seiten läuft, springen Sie zu Frage 3. Andernfalls sehen Sie mit
-h <algo> für die Umgebung nach, die die Liste lesen muss, und streichen Sie
alles, was sie nicht berechnen kann. Diese Frage entscheidet mehr echte Fälle als
kryptografische Stärke.
3. Lässt sich die Prüfliste selbst schützen?
Schreibgeschützte Medien, eine getrennte Maschine oder eine Signatur — gut, dann genügt ein
einfacher Hash. Muss die Liste neben den Daten auf beschreibbarem Speicher liegen, brauchen Sie
HMAC mit einem anderswo aufbewahrten Schlüssel.
4. Wie lange muss das halten?
Wochen: jede ungebrochene Funktion genügt. Jahre bis Jahrzehnte: beschränken Sie sich auf
Prüfungsstufe 1 oder 2 mit ≥ 256 Bit und erwägen Sie Frage 5.
5. Werden die Daten den Algorithmus überleben?
Wenn es in zehn Jahren unmöglich oder nicht vertrauenswürdig ist, die Quelldaten erneut zu lesen,
halten Sie jetzt zwei strukturell verschiedene Hashwerte fest — siehe
Verketten. Ein CPU-Thread heute erkauft Ihnen eine Prüfliste, die die
Abkündigung eines ihrer Algorithmen übersteht.
Ist ein Angreifer möglich?
│
┌─────────┴─────────┐
nein ja
│ │
crc32c / crc64_nvme Müssen andere Werkzeuge prüfen?
(schnell, für │
Zufälle genug) ┌─────────┴────────┐
ja nein
│ │
sha-256 sha3-256
│ │
└────────┬────────┘
│
Liegt die Prüfliste selbst
außerhalb der Reichweite des Angreifers?
│
┌────────┴────────┐
ja nein
│ │
so lassen hmac:<algo> -k
│
Müssen die Daten den
Algorithmus überleben?
│
┌────────┴────────┐
nein ja
│ │
so lassen sha256+sha3-256
Die resultierenden Empfehlungen
| Situation | Wahl | Warum |
|---|---|---|
| Angreifer möglich, Interoperabilität nötig | sha-256 |
die einzige universell unterstützte ungebrochene Funktion |
| Angreifer möglich, Jacksum auf beiden Seiten | sha3-256 |
Schwamm, kein Length-Extension, enormer Sicherheitsabstand; seit 3.0.0 Jacksums Standard |
| Langzeitarchiv | sha256+sha3-256 |
übersteht die Abkündigung einer der Funktionen, ein Lesedurchgang |
| Mehr Reserve gewünscht | sha-512/256 oder sha-512 |
512-Bit-Innenleben; /256 beseitigt zusätzlich Length-Extension |
| Liste liegt in Reichweite eines Angreifers | hmac:sha256 -k … |
authentifiziert die Liste, nicht nur die Dateien |
| Nur Zufälle, oder Protokollkonformität | crc32c, crc64_nvme |
am schnellsten, mit echten Fehlererkennungsgarantien |
| Eine Altliste lesen | was auch immer sie nutzte | Grenzen mit --info -V details prüfen und mit etwas Aktuellem neu hashen |
Der vollständige Ablauf für das Szenario, mit dem diese Anleitung begann. Jedes Kommando unten
wurde gegen Jacksum 4.0.0 ausgeführt.
1. Den Kandidaten begründen. Bevor Sie einem Algorithmus ein Archiv anvertrauen, sehen Sie ihn
sich an:
$ jacksum -a sha-256 --info --verbose details
Prüfen Sie vier Dinge: broken: sagt no, die Begründung dahinter beruhigt, der mittlere
Lawineneffekt liegt nahe 50 %, und die Breite beträgt mindestens 256 Bit.
2. Prüfen, ob die Zukunft es lesen kann.
$ jacksum -h sha-256
3. Die Implementierung gegenprüfen (siehe oben):
$ jacksum -a sha-256 -q txt:"abc"
$ jacksum -A -a sha-256 -q txt:"abc"
$ printf 'abc' | sha256sum
Alle drei müssen ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad ausgeben.
4. Die Prüfliste erzeugen. Beachten Sie, dass die Optionen vor den Dateiparametern stehen
und dass --style full Hashwert, Zeitstempel, Größe und Name festhält:
$ jacksum -a sha-256 --style full -o files.sha256 -r max /data
Nützliche Ergänzungen:
| Option | Wirkung |
|---|---|
-r max |
vollständige Rekursion (der Standard, wenn -r weggelassen wird; -r <n> begrenzt die Tiefe) |
--header |
schreibt einen Kopf mit Version, Betriebssystem, JVM, Datum und Aufruf |
--path-relative-to <path> |
speichert relative Pfade, damit die Liste ein Verschieben übersteht |
-8 / --utf8 |
UTF-8-Ausgabe — tun Sie das, wenn Dateinamen nicht rein ASCII sind |
--charset-output-file <cs> |
expliziter Zeichensatz für die Liste |
-u errors.txt |
sammelt unlesbare Dateien, statt sie im Scrollpuffer zu verlieren |
-E base64 |
eine kompaktere Kodierung als Hex |
Der Stil full ist die zusätzlichen Bytes wert: Größe und Zeitstempel festzuhalten kostet nichts
und gibt Ihnen etwas in der Hand, wenn eine Prüfung fehlschlägt.
5. Die Archivvariante — zwei Algorithmen, ein Lesedurchgang, lesbare Spalten:
$ jacksum -a sha256+sha3-256 -F "#HASH{0} #HASH{1} #FILESIZE #FILENAME" -r max /data
6. Die Liste schützen. Kopieren Sie sie auf schreibgeschützte oder offline gehaltene Medien,
signieren Sie sie (gpg --detach-sign files.sha256) oder erzeugen Sie sie mit HMAC und
bewahren Sie den Schlüssel anderswo auf. Diesen Schritt zu überspringen macht den größten Teil der
Arbeit zunichte.
7. Später prüfen. Verwenden Sie dieselben -a und --style wie beim Erzeugen — das ist
wichtig:
$ jacksum -a sha-256 --style full -c files.sha256
Lassen Sie --style full weg, kann Jacksum nicht wissen, dass die Spalten für Zeitstempel und
Größe vorhanden sind, liest sie als Teil des Dateinamens und meldet alles als MISSING. Lassen
Sie -a weg, fällt es auf sha3-256 zurück und alles ist FAILED. Beide Fehlbilder sehen
alarmierend aus und bedeuten nichts.
Der Bericht unterscheidet fünf Ergebnisse:
Jacksum: matches (OK): 2
Jacksum: mismatches (FAILED): 0
Jacksum: new files (NEW): 0
Jacksum: missing files (MISSING): 0
Jacksum: files with errors (ERROR): 0
Jacksum: strict check: PASSED
| Ergebnis | Bedeutung |
|---|---|
OK |
die Datei ist vorhanden und ihr Hashwert stimmt |
FAILED |
vorhanden, Hashwert weicht ab — die Datei hat sich geändert |
MISSING |
in der Liste, nicht auf der Platte |
NEW |
auf der Platte, nicht in der Liste |
ERROR |
konnte nicht gelesen werden |
8. Die strenge Prüfung. --check-strict macht jedes FAILED, MISSING, NEW oder ERROR zu
einem Gesamtfehlschlag, und genau das wollen Sie für "beweise, dass sich nichts geändert hat":
$ jacksum -a sha-256 --style full --check-strict -c files.sha256 /data
Beachten Sie zwei Dinge. Der strenge Modus braucht auch den Verzeichnisparameter, um neu
hinzugekommene Dateien zu erkennen. Und er verlangt --list-filter all (den Standard) — ein Filter
würde das Hashen unterdrücken, von dem die Erkennung abhängt, weshalb die Kombination mit
--list-filter bad von Jacksum abgelehnt wird.
Exit-Codes machen das skriptfähig:
| Code | Bedeutung |
|---|---|
| 0 | alles in Ordnung |
| 1 | mindestens eine Abweichung bei der Prüfung |
| 2 | Parameterfehler |
| 3 | Parse-Fehler in der Prüfdatei |
| 4 | I/O-Fehler |
| 5 | ein gesuchter Hashwert wurde nicht gefunden |
| 6 | die strenge Prüfung ist fehlgeschlagen |
Eine einfache Abweichung endet also mit 1, eine fehlgeschlagene strenge Prüfung mit 6 — in einem
Überwachungsskript lohnt es sich, das zu unterscheiden.
9. Für sehr große Läufe filtern Sie die Ausgabe auf das, was Aufmerksamkeit braucht (ohne
--check-strict):
$ jacksum -a sha-256 --style full --list-filter bad -c files.sha256
bad zeigt nur FAILED, MISSING und ERROR; good zeigt OK und NEW; none gibt nur die
Zusammenfassung aus.
10. Durchsatz einstellen.
$ jacksum -a sha-256 --threads-reading max --style full -o files.sha256 -r max /data
--threads-reading max hilft bei SSD und NVMe, wo parallele Lesevorgänge skalieren; bei einer
einzelnen drehenden Platte kann es schaden, weil das Positionieren der Köpfe der Kostenfaktor ist.
--threads-hashing steuert die Hash-Seite, die ein verketteter Algorithmus nutzt.
11. Stichproben und Suchen, ohne eine vollständige Liste:
$ jacksum -a sha-256 -q txt:"Hello World" -e a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e
$ jacksum -a sha-256 -e <hash> -r max /data # Dateien zu einem Hashwert finden
$ jacksum -a sha-256 -w wanted.txt -r max /data # Dateien zu einem der Hashwerte einer Liste finden
$ jacksum -a sha-256 --style gnu-linux --check-line "<eine Zeile aus einer Liste>"
12. Einen unbekannten Hashwert identifizieren. Wenn Sie die Daten und den Wert haben, aber
nicht den Algorithmus, kann Jacksum danach suchen (-E ist erforderlich):
$ jacksum -a unknown:256 -E hex -q txt:"abc" -e ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad
Trying 55 algorithms with a width of 256 bits that are supported by Jacksum 4.0.0 ...
sha-256
--> SHA-256 (SHA-2 family)
Jedes davon ist verbreitet, und jedes hat einen bestimmten Grund, falsch zu sein.
Einen CRC als Sicherheitsmaßnahme verwenden. Ein CRC ist affin über GF(2); ein Angreifer löst
ein kleines lineares Gleichungssystem, um jeden Wert zu erzwingen. Ihn zu verbreitern hilft nicht,
weil es keine Suche gibt, die man verlängern könnte. Siehe
drei Familien.
Einen CRC ergänzen, "falls der Hash irgendwann gebrochen wird". sha256+crc32c sieht wie eine
mehrschichtige Verteidigung aus und ist keine. Wer eine Kollision für den Hash konstruieren kann,
zwingt den CRC im selben Schritt auf jeden Wert, der zweite Wert kostet also CPU und bringt
überhaupt keine Sicherheit gegen einen Angreifer. Kombinieren Sie stattdessen zwei strukturell
verschiedene kryptografische Hashfunktionen — siehe Verketten.
MD5 wählen, "weil es schneller ist". Ist es nicht. SHA-256 hat in Jacksums Rangliste Gewicht
11, MD5 hat 35 — moderne CPUs beschleunigen SHA-2 und nicht MD5. Der Tausch, den Sie zu machen
glauben, existiert nicht. Siehe Geschwindigkeit.
Einen Hashwert kürzen, um Plattenplatz zu sparen. 32 Byte pro Datei sind 32 MB pro Million
Dateien. Das Kürzen kostet dauerhaft Kollisionsresistenz und bringt nichts ein. Siehe
Stufe A.
Die Prüfliste auf demselben beschreibbaren Datenträger ablegen wie die Daten. Wer die Dateien
ändern kann, kann die Liste ändern. Verwenden Sie schreibgeschützte Medien, einen getrennten Host,
eine Signatur oder HMAC.
Mit anderen Optionen prüfen als erzeugen. --style full weglassen macht jeden Eintrag
MISSING; -a weglassen fällt still auf sha3-256 zurück und macht alles FAILED. Halten Sie
den genauen Aufruf fest — --header tut das für Sie.
Hashwerte über Werkzeuggrenzen hinweg vergleichen, ohne die Kodierung abzugleichen. Derselbe
Wert kann als Kleinbuchstaben-Hex, Großbuchstaben-Hex, dezimal, Base32 oder Base64 ausgegeben
werden. Mehrere Jacksum-Algorithmen geben standardmäßig dezimal aus (alle CRCs und klassischen
Prüfsummen). Wenn zwei Werkzeuge sich widersprechen, prüfen Sie -E und den Stil, bevor Sie eine
Verfälschung vermuten.
partly gebrochen für sicher halten. partly bedeutet, dass mindestens eine zugesicherte
Eigenschaft gefallen ist. Das ist keine bestandene Prüfung, sondern ein Grund zu wechseln. Siehe
was "gebrochen" bedeutet.
Einen exotischen Algorithmus wählen, weil "es keine bekannten Angriffe gibt". Für ein
unerforschtes Design trägt diese Aussage fast keine Information. Lesen Sie den broken:-Text —
Jacksum sagt Ihnen, wenn die Kryptanalyse dünn ist. Siehe Prüfung.
Dateinamen oder Metadaten statt Inhalte hashen. Ein Stil wie names-only,
sizes-and-names oder timestamps-and-names ist für eine schnelle Inventur nützlich und ist
kein Integritätsschutz. Dasselbe gilt für die Spalten mit Größe und Zeitstempel in einer
Full-Style-Liste: hilfreicher Kontext, trivial zu fälschen.
Annehmen, SFV genüge, weil ein Werkzeug es geschrieben hat. CRC-32, Großbuchstaben-Hex, nur
Dateiname, keine Größe. Siehe Stufe B.
Einmal Fingerprints erzeugen und nie wieder prüfen. Eine Prüfliste, die Sie nie verifizieren,
beweist nichts. Planen Sie die Prüfung ein und machen Sie den Exit-Code für etwas sichtbar, das es
bemerkt.
Alles, was diese Anleitung verwendet hat, an einer Stelle.
Einen Algorithmus untersuchen
| Kommando | Zeigt |
|---|---|
jacksum -a <algo> --info |
Breite, Blockgröße, HMAC-Fähigkeit, broken:-Schlagwort, Geschwindigkeitsrang |
jacksum -a <algo> --info -V details |
dasselbe plus Sicherheitsbegründung und Lawinenmessung |
jacksum -a <algo> --info -q <sequence> |
Lawineneffekt, gemessen an Ihrer Eingabe statt an 123456789 |
jacksum -A -a <algo> --info |
welche Implementierung aktiv ist |
jacksum -h <algo> |
vollständige Dokumentation: Typ, Jahr, Standard, Kommentar, broken:, Kompatibilitätsliste |
jacksum -h crc: |
jeden Parameter des Rocksoft (tm) Model |
jacksum -h hmac: |
HMAC-Syntax und Kürzung |
jacksum -h algorithms |
die Dokumentation aller Algorithmen |
jacksum -h examples |
durchgerechnete Beispiele aus der Manpage |
Algorithmen auflisten
| Kommando | Ergebnis |
|---|---|
jacksum -a all -l |
die IDs aller 586 Algorithmen |
jacksum -a all:256 -l |
nur 256-Bit-Ausgaben (55) |
jacksum -a all:8 -l |
nur 8-Bit-Ausgaben (9) — die "zu kurz"-Liste |
jacksum -a all:sha -l |
nur IDs, die "sha" enthalten |
jacksum --hmacs |
die 492 mit HMAC verwendbaren Algorithmen |
jacksum --hmacs -V info |
pro Algorithmus: Ausgabegröße, Blockgröße, empfohlene Mindestwerte für Schlüssel und Kürzung |
jacksum --hmacs -V summary |
nur die Anzahl |
jacksum -a all --info |
den Info-Block für jeden Algorithmus |
Erzeugen, schützen, prüfen
| Kommando | Zweck |
|---|---|
jacksum -a sha-256 --style full -o list.txt -r max /data |
eine Prüfliste erzeugen |
jacksum -a sha256+sha3-256 -F "#HASH{0} #HASH{1} #FILESIZE #FILENAME" -r max /data |
zwei Algorithmen, ein Lesedurchgang |
jacksum -a hmac:sha256 -k password --style full -o list.txt -r max /data |
authentifizierte Prüfliste |
jacksum -a sha-256 --style full -c list.txt |
prüfen |
jacksum -a sha-256 --style full --check-strict -c list.txt /data |
strenge Prüfung (erkennt auch neue Dateien) |
jacksum -a sha-256 --style full --list-filter bad -c list.txt |
nur zeigen, was Aufmerksamkeit braucht |
jacksum -a sha-256 -e <hash> -r max /data |
Dateien zu einem Hashwert finden |
jacksum -a sha-256 -w wanted.txt -r max /data |
Dateien zu einem der Hashwerte einer Liste finden |
jacksum -a unknown:256 -E hex -q <sequence> -e <hash> |
den Algorithmus hinter einem Hashwert identifizieren |
jacksum -a sha-256 --threads-reading max -r max /data |
parallele Lesevorgänge |
Jacksum-Dokumentation
Primärquellen für die Sicherheitsaussagen
Dies sind die Quellen, die Jacksums eigene broken:-Texte anführen; --info -V details gibt für
jeden Algorithmus die jeweils zutreffende aus.
In dieser Anleitung genannte Standards und Arbeiten
cksum)Eine Schlussbemerkung zum Vertrauen. Jede Zahl in dieser Anleitung kam aus Jacksum selbst, und
jedes Kommando ist auf Ihrer Maschine wiederholbar. Das ist Absicht: es geht nicht darum, eine
Empfehlung zu behalten, sondern darum, sie neu herleiten zu können, wenn sich die Empfehlungen
ändern — denn das werden sie. --info -V details ist die Gewohnheit, die es zu behalten lohnt.