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?
quelle
Antworten:
Ihre Münze hat zwei Seiten:
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:
Aber bietet dies echte Sicherheit? Das Gleiche gilt für Ihre…
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
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.
quelle
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.
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