2016-07-20 47 views
3

Zuvor fragte ich eine question über die Kombination von SHA1 + MD5 aber danach verstehe ich Berechnung SHA1 und dann MD5 einer Lagrge-Datei ist nicht so schnell als SHA256. In meinem Fall dauert eine 4,6-GB-Datei mit der Standardimplementierung SHA256 mit (C# MONO) in einem Linux-System etwa 10 Minuten.Holen Sie sich eine Datei SHA256 Hash-Code und Checksum

public static string GetChecksum(string file) 
{ 
    using (FileStream stream = File.OpenRead(file)) 
    { 
     var sha = new SHA256Managed(); 
     byte[] checksum = sha.ComputeHash(stream); 
     return BitConverter.ToString(checksum).Replace("-", String.Empty); 
    } 
} 

Dann las ich this topic und irgendwie nach meinem Code ändern, was sie sagte:

public static string GetChecksumBuffered(Stream stream) 
{ 
    using (var bufferedStream = new BufferedStream(stream, 1024 * 32)) 
    { 
     var sha = new SHA256Managed(); 
     byte[] checksum = sha.ComputeHash(bufferedStream); 
     return BitConverter.ToString(checksum).Replace("-", String.Empty); 
    } 
} 

aber es verfügt nicht über eine solche Zuneigung und dauert ca. 9 Minuten.

Dann versuche ich meine Datei über sha256sum Befehl in Linux für die gleiche Datei zu testen und es dauert etwa 28 Sekunden und sowohl der obige Code und Linux-Befehl geben das gleiche Ergebnis!

Jemand riet mir, über Unterschiede zwischen Hash-Code und Checksum zu lesen, und ich erreiche this topic, die die Unterschiede erklärt.

Meine Fragen sind:

  1. Was zwischen dem obigen Code und Linux sha256sum in der Zeit so unterschiedliche Ursachen?

  2. Was macht der obige Code? (Ich meine, ist es die Hash-Code-Berechnung oder Prüfsummenberechnung? Denn wenn Sie über einen Hash-Code einer Datei und Prüfsumme einer Datei in C# geben, erreichen sie beide den obigen Code.)

  3. Gibt es irgendwelche motivierter Angriff gegen sha256sum, selbst wenn SHA256 kollisionsresistent ist?

  4. Wie kann ich meine Implementierung so schnell wie sha256sum in C# machen?

+0

Gibt es einen Grund, warum Sie 'sha256sum' nicht mit einem' Process' aus Ihrem Code aufrufen können? –

+0

@NateDiamond Ja! Zuerst muss dieses Programm sowohl unter Windows als auch unter Linux laufen. Zweitens ist, wie ich in meiner Frage erwähne, ich nicht ob die Prüfsumme sicher genug ist. (Oder Hash-Code) –

+0

Dies sollte vollständig durch die Kosten des Lesens der Datei von der Festplatte gedrosselt werden. 9 Minuten ist nicht undenkbar, aber Sie würden einen billigen Laptop mit einem beschissenen Spindelantrieb und nicht genug RAM benötigen. Dokumentieren Sie, was Sie verwenden. –

Antwort

4
  1. beste Vermutung ist, dass es einige zusätzliche Pufferung in der Mono-Implementierung des File.Read Betrieb. Nachdem ich kürzlich in einer großen Datei nach Prüfsummen gesucht habe, scheint es, dass man auf einem ordentlichen Spec Windows-Rechner ungefähr 6 Sekunden pro GB erwarten sollte, wenn alles reibungslos läuft. Seltsamerweise wurde in mehr als einem Benchmark-Test berichtet, dass SHA-512 merklich schneller ist als SHA-256 (siehe 3 unten). Eine andere Möglichkeit besteht darin, dass das Problem nicht darin besteht, die Daten zuzuordnen, sondern die einmal gelesenen Bytes zu entsorgen. Sie können möglicherweise TransformBlock (und TransformFinalBlock) auf einem einzigen Array verwenden, anstatt den Stream in einem großen Schluck zu lesen - ich habe keine Ahnung, ob das funktioniert, aber es wird untersucht.

  2. Der Unterschied zwischen Hashcode und Prüfsumme ist (fast) Semantik. Sie berechnen beide eine kürzere "magische" Zahl, die ziemlich einzigartig für die Daten in der Eingabe ist, obwohl, wenn Sie 4,6 GB Input und 64B Output haben, "fair" etwas begrenzt ist. Eine Prüfsumme ist nicht sicher, und mit ein wenig Arbeit können Sie die Eingabe von genügend Ausgaben herausfinden, rückwärts von Ausgabe zu Eingabe und allerlei unsicherer Dinge arbeiten. Ein kryptografischer Hash dauert länger zu berechnen, aber das Ändern nur eines Bits in der Eingabe wird die Ausgabe radikal ändern, und für einen guten Hash (z.B. SHA-512) gibt es keine bekannte Möglichkeit, von Ausgabe zurück zu Eingabe zu gelangen.

  3. MD5 ist zerbrechlich, Sie können einen Eingang herstellen, um eine beliebige Ausgabe bei Bedarf auf einem PC zu erzeugen.SHA256 ist (wahrscheinlich) immer noch sicher, wird aber in ein paar Jahren nicht mehr sein - wenn Ihr Projekt eine in Jahrzehnten gemessene Lebensdauer hat, dann nehmen Sie an, dass Sie es ändern müssen. SHA512 hat keine bekannten Attacken und wird es wahrscheinlich eine ganze Weile nicht tun, und da es schneller ist als SHA256, würde ich es trotzdem empfehlen. Benchmarks zeigen, dass die Berechnung von SHA512 etwa 3-mal länger dauert als die von MD5. Wenn also Ihr Geschwindigkeitsproblem gelöst werden kann, ist dies der richtige Weg.

  4. Keine Ahnung, abgesehen von den oben genannten, machst du es richtig.

Für ein bisschen Unterhaltungslektüre https://crypto.stackexchange.com/questions/26336/sha512-faster-than-sha256

bearbeiten als Antwort auf Kommentar zu hinterfragen

Der Zweck einer Prüfsumme ist, dass Sie, wenn eine Datei zwischen der Zeit geändert hat, zu überprüfen, um zu ermöglichen, Du hast es ursprünglich geschrieben und die Zeit, die du damit verbringst. Dies geschieht durch Erzeugen eines kleinen Wertes, 512 Bit im Fall von SHA512, wobei jedes Bit der ursprünglichen Datei zumindest etwas zu dem Ausgabewert beiträgt. Der Zweck eines Hashcodes ist derselbe, mit dem Zusatz, dass es wirklich, wirklich schwierig für jeden anderen ist, den gleichen Ausgabewert zu erhalten, indem sorgfältig verwaltete Änderungen an der Datei vorgenommen werden. Die Voraussetzung ist, dass, wenn die Prüfsummen am Anfang gleich sind und wenn Sie es überprüfen, die Dateien die gleichen sind, und wenn sie unterschiedlich sind, hat sich die Datei sicherlich geändert. Was Sie oben tun, ist das Füttern der Datei in ihrer Gesamtheit durch ein Algorithm, das die gelesenen Bits rollt, faltet und spindelt, um den kleinen Wert zu erzeugen.

Als Beispiel, in der Anwendung, die ich gerade schreibe, muss ich wissen, ob Teile einer Datei jeder Größe geändert haben, also teile ich die Datei in 16K Blöcke, nehmen Sie den SHA-512-Hash von jedem Block und Speichern Sie es in einer separaten Datenbank auf einem anderen Laufwerk. Wenn ich sehe, ob sich die Datei geändert hat, gebe ich den Hash für jeden Block wieder und vergleiche ihn mit dem Original. Da ich SHA-512 verwende, sind die Chancen, dass sich eine Datei ändert, aber der Hashwert gleich bleibt, unvorstellbar klein, so dass ich sicher bin, Änderungen in 100 GB Daten zu erkennen und nur ein paar MB Hashes in meiner Datenbank zu speichern. Ich kopiere die Datei gleichzeitig mit dem Hash, und der Prozess ist vollständig diskettengebunden; Es dauert ungefähr 5 Minuten, um eine Datei auf ein USB-Laufwerk zu übertragen, von dem 10 Sekunden wahrscheinlich mit dem Hashing zusammenhängen.

Der Mangel an Speicherplatz zum Speichern von Hashes ist ein Problem, das ich nicht in einem Post lösen kann ... einen USB-Stick kaufen?

+0

nun, es ist erstaunlich, dass sha256 langsamer ist als sha512! Nun, ich habe eine andere Frage. Was ist der Code, den ich oben erwähnt habe? Es könnte lächerlich sein, aber ich kann nichts anderes finden, wenn ich nach 'Get file Checksum' und 'Get file hash' suche. Sie geben beide das gleiche Ergebnis. Scheint, dass die Leute nicht wissen, was sie genau machen :). (Wie ich!) –

+0

Und eine andere Sache ist, kann ich 128 Byte für sha512 nicht speichern! Da sind Tonnen von Dateien und ich habe nicht genug Volumen. –

+0

Antwort bearbeiten als Antwort –