Schnelles Hashing: Kombination verschiedener Techniken, um Änderungen in einer Datei zu identifizieren?

9

Ich möchte einen schnellen Weg finden, um festzustellen, ob eine Datei identisch sein kann oder nicht. Für eine fast 100% ige Sicherheit würde ich einen vorhandenen Hash-Algorithmus verwenden, z. B. SHA256. Es wird jedoch erwartet, dass es sich bei den Dateien um riesige Videodateien mit mehreren GB handelt. Daher kann die Berechnung des SHA256-Hash einige Zeit in Anspruch nehmen, insbesondere über das Netzwerk.

Deshalb möchte ich verschiedene andere Techniken kombinieren:

  • Dateigröße: Wenn sich die Dateigröße geändert hat, hat sich der Inhalt geändert (sicher)
  • Kopf / Schwanz-Hash
  • zufälliger Hash

Die letzteren 2 sind Teil meiner Frage:

Meine Vermutung wäre, dass es in der Kopfzeile Dinge gibt wie:

  • Bildraten (zB Videos)
  • Auflösung (zB Videos, Bilder)
  • (Datei-) Länge (z. B. in Frames, Pixeln usw.)
  • Datum der letzten Änderung (z. B. Word-Dokumente, nicht speziell Videos)

Warum ich erwäge, den Schwanz zu überprüfen, ist:

  • MP3 hat dort die Tag-Informationen
  • EXIF fügt am Ende benutzerdefinierte Daten hinzu, wenn ich recht habe

Zufällige Hashes würden z. B. 126 Regionen an zufälligen Positionen in der Datei mit einer bestimmten Länge auswählen, z. B. 64 kB, und einen Hash für sie erstellen. Natürlich erinnere ich mich an die Offsets für einen späteren Vergleich. Alles in allem würde ich (1 + 126 + 1) * 64 kB Daten für meinen Hash verwenden, daher muss ich nur 8 MB anstelle mehrerer GB lesen, um den Hash zu erhalten.

Vielleicht ist es jetzt eher eine mathematische Frage, aber: Wie wahrscheinlich ist es, dass eine Änderung mithilfe der Kombination aus Dateigröße, Kopf-, End- und Zufallsdaten erkannt wird, um diese schnelle Hash-Summe zu generieren?

Ich gehe davon aus, dass die Dateien immer legale Dateien sind. Es hat keinen Vorteil, einzelne Bytes zu manipulieren. Der Benutzer würde ein normales Videobearbeitungswerkzeug verwenden, um die Dateien zu ändern.

UPDATE : Ich habe diese Antwort von Crypto.StackExchange nicht akzeptiert. Ich bin damit einverstanden, dass mein Vorschlag nicht kryptografisch ist und nicht sicher sein soll. Ich stimme auch zu, dass das CRCing einer Datei schnell ist, aber in meinem Fall brauche ich wirklich einen Hash - ich werde erklären, warum:

  • Von meiner Anwendung wird erwartet, dass sie Lesezeichen in Videos speichert. Von meiner Datenbank wird erwartet, dass sie den Video-Hash und die Lesezeichen speichert.
  • Benutzer verschieben oder benennen manchmal Dateien um. Mein Programm wird feststellen, dass eine Datei nicht mehr vorhanden ist, die Lesezeichen jedoch nicht aus der Datenbank löschen. Wenn dasselbe Video (versehentlich) erneut abgespielt wird, möchte ich stattdessen erkennen, dass es sich (wahrscheinlich) um dieselbe Datei handelt.
  • Von Benutzern wird erwartet, dass sie Dateien auf Netzwerklaufwerken (NAS) speichern und Videos streamen. Das sind dumme Speicher. Ich kann keine Serverkomponente installieren. Und sie könnten ziemlich langsam sein, also möchte ich wirklich nicht den vollen Hash. Die Berechnung eines vollständigen Hashs für eine 3-GB-Datei dauert mindestens 5 Minuten bei 10 MB / s, unabhängig davon, wie schnell der Hashing-Algorithmus ist.
  • Wenn der Benutzer die Datei bearbeitet hat, hoffe ich irgendwie, dass der Hash nicht mehr übereinstimmt, da ich sonst falsche Lesezeichen anzeigen würde.

Ich hätte eine Chance von ~ 80% , die richtigen Lesezeichen zu haben. Wie viele Hash-Teile sollte ich zusammenstellen und wo in der Datei wäre das?

Thomas Weller
quelle
1
Solange böswillige Manipulationen oder Dateibeschädigungen kein Problem darstellen, ist dies nicht erforderlich. Verwenden Sie einfach ein spezielles Programm, um die Header der Mediendatei zu interpretieren, die die Codierungs- / Kennzeichnungsdaten und -größen der Streams enthalten sollten. Sie können die Medieninformationen zum einfachen Vergleich hashen.
Außerdem halten die meisten Betriebssysteme für jede Datei ein Datum der letzten Änderung bereit. Wenn Sie sich keine Gedanken über böswillige Manipulationen machen müssen (das Datum der letzten Änderung kann im Allgemeinen von jemandem festgelegt werden), können Sie sich das einfach ansehen und sich überhaupt nicht um Dateiinhalte kümmern.
Poncho
EXIF oder MP3tag sind fast unbrauchbar, um Änderungen zu erkennen: Viele Manipulationsprogramme können diese nicht berühren, sodass sie ihren vorherigen Inhalt beibehalten. Zum Beispiel kann EXIF ​​das Originalbild beibehalten .
1
Wenn Sie sagen: "Ich gehe davon aus, dass es sich bei den Dateien immer um legale Dateien handelt", suchen Sie vermutlich keine Sicherheit? In diesem Fall befinden Sie sich auf der falschen Website. Informatik sollte eine bessere Hilfe sein. Die Antworten, die Sie hier erhalten haben, sind irrelevant, wenn Sie keine Sicherheit wünschen. Wenn dies der Fall ist, würde ich vorschlagen, die Informatik erneut zu veröffentlichen und diesen Punkt in Ihrer erneut gestellten Frage zu klären.
Gilles 'SO - hör auf böse zu sein'
2
1) Die tatsächliche Hash-Berechnung ist im Vergleich zum IO normalerweise günstig. MD5 erkennt alle nicht böswilligen Änderungen und ist ziemlich schnell. Vor allem, wenn Sie es parallelisieren. Sie benötigen ein RAID von SSDs oder etwas ähnlich schnelles, um seine Geschwindigkeit zu überschreiten. 2) Bei lokalen Dateien kann das Betriebssystem häufig feststellen, ob es sich geändert hat. Es gibt nicht nur das Datum der letzten Änderung, sondern auch einige spezielle APIs.
CodesInChaos

Antworten:

8

Ihre Münze hat zwei Seiten:

  1. Wenn Sie es sicher machen möchten, müssen Sie einen kryptografisch sicheren Hash wie SHA256 verwenden (Krypto-Hashes sollen schnell sein, sind aber aus Sicherheitsgründen etwas langsam).
  2. Dinge wie CRCs sind definitiv schneller, werden aber niemals die gleiche Art von Sicherheit bieten können (besonders wenn wir darüber sprechen.

Option 1: CRCs - Schnell zum Preis der Sicherheit:

Wenn Sie kurz nach dem Erkennen von Änderungen sind, wählen Sie eine Prüfsumme anstelle eines Hashs. Dafür wurden Prüfsummen erstellt: schnelles Erkennen von Änderungen in einer Datei oder einem Datenstrom. Beachten Sie jedoch, dass CRC entwickelt wurde, um Übertragungsfehler und keine böswilligen Aktionen zu verhindern!

In der Praxis ist CRC32 der naheliegendste Kandidat (aber selbst ein additiver CRC8 würde den Job erledigen, wenn Sie nur feststellen möchten, ob sich etwas geändert hat, und vom CRC nichts anderes erwarten.)

Option 2: Über CRCs hinaus - Gehen Sie schnell vor und verbessern Sie gleichzeitig die Änderungserkennung:

Andere gültige Optionen (siehe @ ponchos Kommentar ) sind in der Tat, einfach den Zeitstempel der letzten Modifikation zu überprüfen .

Oder Sie kombinieren beide (um Engpässe zu vermeiden) und verwenden so etwas wie diesen Pseudocode:

if(LastMod != knownLastMod) { CreateNewCRCandCompare(FileName, knownCRC) };

Aber bietet dies echte Sicherheit? Das Gleiche gilt für Ihre…

Warum ich in Betracht ziehe, den Schwanz zu überprüfen, ist:
- MP3 enthält dort die Tag-Informationen
- EXIF ​​fügt am Ende benutzerdefinierte Daten hinzu, wenn ich Recht habe

Auch hier kommt es darauf an, wie viel Sicherheit Sie erwarten. Sie müssen sich darüber im Klaren sein, dass ein Gegner die Datei mit Sicherheit manipulieren wird, um alte ID3- und EXIF-Daten beizubehalten (oder zu kopieren und einzufügen). Jeder (mit entsprechenden RW-Dateizugriffsrechten) kann dies ändern. Gleiches gilt für den Zeitstempel der letzten Änderung, die Bildraten, die Auflösung, das Datum der letzten Änderung und sogar die (Datei-) Länge. Abhängig davon würden "zusätzliche" und "modifizierbare" Daten, die von jedem mit ausreichenden Dateizugriffsrechten geändert und entfernt werden können, eine Sicherheitslücke verursachen.

Aber Sie erwarten Sicherheit, nicht wahr? Das ist schließlich der Grund, warum Sie überhaupt darüber nachdenken. Dann führt kein Weg an kryptosicheren Hashes vorbei…

Option 3: Kryptografisch sichere Hashes - Sicher zum Preis der Geschwindigkeit:

Wenn Sie echte Sicherheit erwarten, müssen Sie sich auf Hashing verlassen. Genauer gesagt: kryptografisch sicheres Hashing (unter Verwendung eines Hashs, von dem nicht bekannt ist, dass er Kollisionen erzeugt). Es braucht Zeit (ein paar Mikrosekunden pro MB), aber es lohnt sich.

Meine 2 (persönlichen) Cent:

Versuchen Sie, mit der Tatsache zu leben, dass Hashing Zeit kostet, und hacken Sie die gesamten Dateien mit einem kryptografisch sicheren Hash. Denn wenn etwas anfängt, den Fan zu treffen, ist es besser, langsam zu sein, als sich zu entschuldigen.

BEARBEITEN basierend auf Ihrer BEARBEITUNG…

Wenn die kryptografische Sicherheit nicht Ihr Hauptaugenmerk ist, können Sie sich MD5 oder SHA1 ansehen. Sowohl MD5 als auch SHA1 sind „kryptografisch defekt“, da Kollisionen erkannt wurden. Für die von Ihnen beschriebenen Änderungserkennungszwecke (insbesondere nach Ihrer Bearbeitung) sollte die Wahrscheinlichkeit, eine solche Kollision zu treffen, jedoch minimal genug sein.

Wenn ich alles noch einmal betrachte (einschließlich Ihrer EDIT), würde ich persönlich höchstwahrscheinlich MD5 verwenden, da es eine brauchbare Kollisionsbeständigkeit (für Änderungserkennungszwecke) bietet und dennoch schnell genug ist, um Multi-Gigabyte-Dateien vollständig zu hashen.

Wenn Sie dies immer noch nicht im Sinne von „Geschwindigkeit“ befriedigt oder wenn Ihre Hardwareressourcen wirklich so begrenzt sind, müssen Sie versuchen, Kollisionsbeständigkeit / Änderungserkennung mit Geschwindigkeit in Einklang zu bringen. Bedeutung…

Nehmen Sie den individuellen Zeitstempel, den individuellen Dateinamen und den Hash des Headers (Länge hängt vom Medientyp und dem verwendeten Dateiformat ab) sowie einen guten Teil aus der Mitte und einen guten Teil des Endes (= Dateiende). Kombinieren Sie diese 5 und Sie sollten in der Lage sein, die meisten grob herauszufiltern

Ich hätte eine Chance von ~ 80%, die richtigen Lesezeichen zu haben. Wie viele Hash-Teile sollte ich zusammenstellen und wo in der Datei wäre das?

Dies ist eher eine persönliche Meinung, da es von einer ganzen Reihe von Details abhängt (Medientyp, Dateiformat, verfügbare Ressourcen, erwartetes Änderungserkennungsverhältnis, Dateiähnlichkeit usw.). Sie müssen dies also je nach Ihrer persönlichen Meinung ausgleichen Erwartungen, Ihre Implementierungen und lokale Ergebnisse aufgrund von Hardware- und / oder Softwareengpässen.

Lassen Sie mich dennoch versuchen, Ihnen eine Anleitung zu geben:

Wenn das Hashing der vollständigen Datei aus irgendeinem Grund keine Option ist, würde ich - zumindest - Folgendes nehmen: den Header (und vielleicht ein paar KB mehr), einen guten Teil aus der Mitte (zumindest die Größe des „Headers & Co. . ”Teil) und einen guten Teil vom Dateiende (wieder mindestens die Größe des Teils’ header & co. ”).

Je mehr Ressourcen Sie investieren können (oder bereit sind zu investieren), desto mehr Brocken können Sie nehmen und / oder desto größer können diese Chunks sein. Wenn Sie der Meinung sind, dass Ihre Ressourcen / Ihr Gefühl / was auch immer noch Platz für mehr bietet, erhöhen Sie die Größe der Chunks, die Sie hashen, und / oder erhöhen Sie die Anzahl der Chunks, die Sie hashen.

Das Erhöhen der Anzahl der Chunks ist einfach: Sie müssen lediglich auf eine gleichmäßige Verteilung achten (indem Sie die Dateigröße entsprechend teilen, was zu Chunks gleicher Größe führt, die Sie aus Teilen mit gleichem Abstand über die gesamte Dateilänge extrahieren).

Und wenn Sie sich fragen: „Warum gleichmäßig verteilte und nicht zufällige Blockpositionen?“, Lassen Sie mich einfach beachten, dass die Auswahl zufälliger Blockpositionen Ihre Bemühungen zur Erkennung von Änderungen praktisch ungültig machen kann, da das Risiko besteht, dass einige wichtige Teilemedien übersprungen werden Normalerweise erkennen Sie die Chancen, die Sie erkennen möchten. Die Wahl einer gleichmäßigen Verteilung ist - einfach gesagt - neutraler.

E-Sushi
quelle
1
Ich würde CRC32 nicht verwenden, eine zu große Ausfallwahrscheinlichkeit auch ohne böswillige Angriffe. Krypto ist ziemlich schnell. Sie sollten 1 GB / s auf einem einzelnen Kern mit einem Standard-Hash erhalten. Wenn Sie es etwas schwächen, sollten 3 GB / s möglich sein. Es ist fast sicher, dass E / A teurer ist als Hashing.
CodesInChaos
@CodesInChaos Ich stimme zu. Deshalb raten meine abschließenden Worte zu einem kryptografisch sicheren Hash.
E-Sushi
1
Carter-Wegman-Hashes und andere universelle Hashes könnten helfen. Diese haben die Geschwindigkeit eines breiten CRC und die Sicherheit von Hashes, vorausgesetzt, ein Schlüssel bleibt dem Angreifer unbekannt und wird nicht wiederverwendet. Siehe diese Antwort für Referenzen.
fgrieu
@fgrieu Aber würde das nicht bedeuten, dass OP in OP-Situationen einen individuellen Schlüssel pro Datei benötigt? Scheint mir ein bisschen unpraktisch. Insbesondere, da dies die Notwendigkeit einer Schlüsselverwaltung usw. einführen würde, nur um mögliche Dateimodifikationen zu überprüfen.
E-Sushi
1
@ e-suschi: Wenn es eine eindeutige Dateikennung gibt (z. B. einen Pfad), reicht ein Hauptschlüssel und HMAC aus, um einen eindeutigen Schlüssel pro Datei zu erhalten. Das heißt, wenn die Gegnerin Lesezugriff auf den Schlüssel erhält, kann sie eine Fälschung vornehmen, wenn sie dies nicht mit einem regulären Hash der Datei und schreibgeschütztem Zugriff kann.
Fgrieu
5

Verknüpfungen

Wenn Sie mehrere Dateien haben und Änderungen an Dateien erkennen möchten, verwenden Sie die Dateigröße und den Zeitstempel für die letzte Änderung.

Es ist möglich, dass das von Ihnen verwendete Betriebssystem Funktionen zum Erkennen von Dateiänderungen bietet. Beispielsweise ermöglicht Linux das Benachrichtigen über Änderungen an Verzeichnissen.

Vollständige Dateiverarbeitung

Wenn Sie den tatsächlichen Inhalt von Dateien lesen müssen, um zu überprüfen, ob sich die Dateien geändert haben, verwenden Sie den tatsächlichen kryptografischen Hash. CRC hat ein erhebliches Potenzial für ein falsches Negativ. SHA-256 kann ziemlich gut sein, aber tatsächlich ist SHA-512 auf vielen modernen Plattformen schneller.

Wenn Sie über viele CPU-Kerne verfügen, kann es hilfreich sein, verschiedene Hashes für verschiedene Teile der Datei zu berechnen oder einen Hash-Baum zu verwenden, um die Verarbeitung zu parallelisieren.

Der Grund für den Vorschlag eines richtigen Hashs ist, dass die kryptografische Verarbeitung nicht zu umfangreich ist, sobald Sie zu den tatsächlichen Dateidaten wechseln. Stattdessen gibt es viele andere langsamere Dinge, z. B. Festplatten-E / A oder Senden und Empfangen von Netzwerkpaketen.

Hinweis: Für (mindestens) kleine Dateien ist es auch möglich, den gesamten Dateiinhalt zu speichern und den Inhalt anstelle von Hash zu vergleichen.

Hinweis 2: Wenn der Speicher sehr knapp ist, ist CRC oder abgeschnittener kryptografischer Hash möglicherweise eine gute Wahl. CRC32 benötigt 4 Bytes pro Datei und SHA-256 32 Bytes. Kleine Tags mit 4 Byte können nicht vor böswilligen Versuchen schützen, Änderungen auszublenden.

Teilweise Dateiverarbeitung

In den meisten Fällen würde ich empfehlen, nur die vollständige Dateiverarbeitung zu verwenden.

Vielleicht ist es jetzt eher eine mathematische Frage, aber: Wie wahrscheinlich ist es, dass eine Änderung mithilfe der Kombination aus Dateigröße, Kopf-, End- und Zufallsdaten erkannt wird, um diese schnelle Hash-Summe zu generieren?

Bei Bilddateien ist es üblich, kleine Änderungen vorzunehmen, z. B. rote Augen zu entfernen, Schnurrbart oder Hörner hinzuzufügen usw. Diese Änderungen im JPG-Format wirken sich gelegentlich nicht auf die Dateigröße aus (mit einem Bearbeitungsprogramm, das Änderungen an JPG vornehmen kann, wobei die Neukomprimierung nur geändert wird Bereiche) oder eines der anderen Attribute, die Sie erwähnen.

Die Änderungszeit der Datei wird jedoch normalerweise beeinflusst.

Berücksichtigung von Videodateien: Viele Videoformate erzeugen eine konstante Bitrate. Wenn bei einer Datei mit konstanter Bitrate einige Frames in der Mitte geändert werden, wird sie auch nicht in Dateigröße, Kopf oder Schwanz angezeigt. Das Entfernen oder Hinzufügen von Frames führt fast immer zu Größenunterschieden.

Ich sehe es also durchaus möglich, dass das Feld Änderungen erhält, ohne dass es erkannt wird.

Es ist sehr schwer zu schätzen, dass mit diesem Schema Wahrscheinlichkeitsänderungen erkannt werden. Es gibt jedoch häufig verwendete Verwendungsszenarien für Videos und Bilder, die nicht ordnungsgemäß erkannt werden.


quelle
Ja, kleine Änderungen an PNG- oder WAV-Dateien können mit großer Wahrscheinlichkeit übersehen werden, wenn nur einige Blöcke verarbeitet werden.
Galinette