541 Stimmen

Grundlegender Unterschied zwischen Hashing- und Verschlüsselungsalgorithmen

Ich sehe eine Menge Verwirrung zwischen Hashes und Verschlüsselungsalgorithmen und würde gerne mehr Expertenrat dazu hören:

  1. Wann Hashes und wann Verschlüsselungen verwendet werden sollten

  2. Was macht einen Hash- oder Verschlüsselungsalgorithmus aus (theoretisch/mathematisch) d.h. was macht Hashes unumkehrbar (ohne Hilfe eines Regenbogenbaums)

Hier sind einige ähnlich SO Fragen, die nicht so sehr ins Detail gehen, wie ich es gesucht habe:

Was ist der Unterschied zwischen Obfuscation, Hashing und Encryption?
Unterschied zwischen Verschlüsselung und Hashing

31 Stimmen

Ich kann mir vorstellen, dass dies die Frage, auf die sich die Leute beziehen können, wenn sie die Begriffe verwechseln :)

20 Stimmen

Hashing ist einseitig (kann nicht rückgängig gemacht werden), Verschlüsselung ist zweiseitig (kann entschlüsselt werden)

1 Stimmen

Hashes sind auch nützlich für die Indizierung großer Strukturen und Objekte, z. B. Dateien. Siehe Hash-Tabelle .

781voto

ircmaxell Punkte 159431

Nun, Sie könnten es nachschlagen in Wikipedia ... Aber da Sie eine Erklärung wollen, werde ich mein Bestes tun:

Hash-Funktionen

Sie bieten eine Zuordnung zwischen einer Eingabe beliebiger Länge und einer (normalerweise) festen Länge (oder kleineren Länge) der Ausgabe. Das kann alles sein, von einem einfachen crc32 bis hin zu einer vollwertigen kryptographischen Hash-Funktion wie MD5 oder SHA1/2/256/512. Der Punkt ist, dass es sich um eine einseitige Zuordnung handelt. Es ist immer eine viele:1-Zuordnung (d.h. es wird immer Kollisionen geben), da jede Funktion eine kleinere Ausgabe produziert, als sie eingeben kann (wenn man jede mögliche 1mb-Datei in MD5 einspeist, wird man eine Menge Kollisionen bekommen).

Der Grund, warum sie nur schwer (oder praktisch gar nicht) rückgängig zu machen sind, liegt in ihrer internen Funktionsweise. Die meisten kryptografischen Hash-Funktionen durchlaufen den Eingabesatz viele Male, um die Ausgabe zu erzeugen. Wenn wir uns also jedes Stück der Eingabe mit fester Länge ansehen (was vom Algorithmus abhängt), bezeichnet die Hash-Funktion dies als den aktuellen Zustand. Dann durchläuft sie diesen Zustand, ändert ihn in einen neuen und verwendet ihn als Rückmeldung für sich selbst (MD5 tut dies 64 Mal für jedes 512-Bit-Datenpaket). Anschließend werden die sich aus all diesen Iterationen ergebenden Zustände irgendwie miteinander kombiniert, um den resultierenden Hashwert zu bilden.

Wollte man nun den Hash entschlüsseln, müsste man zunächst herausfinden, wie man den gegebenen Hash in seine iterierten Zustände aufteilt (1 Möglichkeit für Eingaben, die kleiner sind als die Größe eines Datenpakets, viele für größere Eingaben). Dann müsste man die Iteration für jeden Zustand umkehren. Um zu erklären, warum das SEHR schwierig ist, stellen Sie sich vor, dass Sie versuchen, Folgendes abzuleiten a y b nach der folgenden Formel: 10 = a + b . Es gibt 10 positive Kombinationen von a y b die funktionieren können. Jetzt wiederholen Sie das ein paar Mal: tmp = a + b; a = b; b = tmp . Bei 64 Iterationen hätte man über 10^64 Möglichkeiten zum Ausprobieren. Und das ist nur eine einfache Addition, bei der ein gewisser Zustand von Iteration zu Iteration erhalten bleibt. Echte Hash-Funktionen führen viel mehr als eine Operation durch (MD5 führt etwa 15 Operationen an 4 Zustandsvariablen durch). Und da die nächste Iteration vom Zustand der vorherigen abhängt und der vorherige Zustand bei der Erzeugung des aktuellen Zustands zerstört wird, ist es nahezu unmöglich, den Eingangszustand zu bestimmen, der zu einem bestimmten Ausgangszustand geführt hat (und das bei jeder Iteration). Kombiniert man dies mit der großen Anzahl von Möglichkeiten, die damit verbunden sind, so erfordert die Dekodierung selbst eines MD5 eine nahezu unendliche (aber nicht unendliche) Menge an Ressourcen. So viele Ressourcen, dass es deutlich billiger ist, den Hash zu erzwingen, wenn man eine Vorstellung von der Größe der Eingabe hat (bei kleineren Eingaben), als zu versuchen, den Hash zu entschlüsseln.

Verschlüsselungsfunktionen

Sie bieten eine 1:1-Abbildung zwischen einer Eingabe und einer Ausgabe beliebiger Länge. Und sie sind immer umkehrbar. Wichtig ist, dass sie mit einer bestimmten Methode umkehrbar sind. Und es ist immer 1:1 für einen bestimmten Schlüssel. Nun gibt es mehrere Eingabe-Schlüssel-Paare, die dieselbe Ausgabe erzeugen können (je nach Verschlüsselungsfunktion gibt es das in der Regel). Gute verschlüsselte Daten sind von zufälligem Rauschen nicht zu unterscheiden. Dies unterscheidet sich von einer guten Hash-Ausgabe, die immer ein einheitliches Format hat.

Anwendungsfälle

Verwenden Sie eine Hash-Funktion, wenn Sie einen Wert vergleichen wollen, aber die einfache Darstellung nicht speichern können (aus einer Vielzahl von Gründen). Passwörter eignen sich sehr gut für diesen Anwendungsfall, da man sie aus Sicherheitsgründen nicht im Klartext speichern möchte (und sollte). Was aber, wenn man ein Dateisystem auf raubkopierte Musikdateien überprüfen möchte? Es wäre unpraktisch, 3 MB pro Musikdatei zu speichern. Nehmen Sie stattdessen den Hash der Datei und speichern Sie diesen (md5 würde 16 Byte statt 3 MB speichern). Auf diese Weise kann man einfach jede Datei mit einem Hash versehen und mit der gespeicherten Datenbank von Hashes vergleichen (in der Praxis funktioniert das nicht so gut, weil die Dateien neu codiert werden, die Dateiköpfe geändert werden usw., aber es ist ein Beispiel für einen Anwendungsfall).

Verwenden Sie eine Hash-Funktion, wenn Sie die Gültigkeit von Eingabedaten überprüfen. Dafür sind sie ja gedacht. Wenn Sie 2 Eingabedaten haben und prüfen wollen, ob sie gleich sind, lassen Sie beide durch eine Hash-Funktion laufen. Die Wahrscheinlichkeit einer Kollision ist bei kleinen Eingabedaten astronomisch gering (eine gute Hash-Funktion vorausgesetzt). Deshalb wird sie für Passwörter empfohlen. Für Passwörter mit bis zu 32 Zeichen hat md5 den 4-fachen Ausgabespeicher. SHA1 hat den 6-fachen Ausgaberaum (ungefähr). SHA512 hat etwa den 16-fachen Ausgabespeicherplatz. Es ist eigentlich egal, wie das Kennwort lautet. war Sie interessiert, ob es die gleiche ist wie die, die gespeichert wurde. Deshalb sollten Sie Hashes für Passwörter verwenden.

Verwenden Sie die Verschlüsselung immer dann, wenn Sie die Eingabedaten wieder herausbekommen müssen. Beachten Sie das Wort brauchen . Wenn Sie Kreditkartennummern speichern, müssen Sie sie irgendwann wieder herausholen, wollen sie aber nicht im Klartext speichern. Speichern Sie stattdessen die verschlüsselte Version und bewahren Sie den Schlüssel so sicher wie möglich auf.

Hash-Funktionen eignen sich auch hervorragend zum Signieren von Daten. Wenn Sie z. B. HMAC verwenden, signieren Sie einen Teil der Daten, indem Sie einen Hash-Wert der Daten mit einem bekannten, aber nicht übertragenen Wert (einem geheimen Wert) verknüpfen. Sie senden also den Klartext und den HMAC-Hash. Der Empfänger verschlüsselt dann einfach die übermittelten Daten mit dem bekannten Wert und prüft, ob er mit dem übermittelten HMAC übereinstimmt. Wenn dies der Fall ist, wissen Sie, dass die Daten nicht von einer Partei manipuliert wurden, die den geheimen Wert nicht kennt. Dies wird häufig in sicheren Cookie-Systemen von HTTP-Frameworks sowie bei der Übertragung von Daten über HTTP verwendet, wenn eine gewisse Integrität der Daten gewährleistet werden soll.

Ein Hinweis zu Hashes für Kennwörter:

Ein wesentliches Merkmal kryptographischer Hash-Funktionen ist, dass sie sehr schnell zu erstellen sind und sehr schwer/langsam rückgängig zu machen (so sehr, dass es praktisch unmöglich ist). Dies stellt ein Problem bei Passwörtern dar. Wenn Sie Folgendes speichern sha512(password) tun Sie nichts, um sich gegen Rainbow Tables oder Brute-Force-Angriffe zu schützen. Denken Sie daran, dass die Hash-Funktion auf Geschwindigkeit ausgelegt ist. Daher ist es für einen Angreifer trivial, einfach ein Wörterbuch durch die Hash-Funktion laufen zu lassen und jedes Ergebnis zu testen.

Das Hinzufügen eines Salzes ist hilfreich, da es dem Hash ein paar unbekannte Daten hinzufügt. Anstatt also etwas zu finden, das mit md5(foo) Sie müssen etwas finden, das in Verbindung mit dem bekannten Salz md5(foo.salt) (was sehr viel schwieriger zu bewerkstelligen ist). Das Geschwindigkeitsproblem ist damit aber immer noch nicht gelöst, denn wenn sie das Salz kennen, müssen sie nur das Wörterbuch durchlaufen lassen.

Es gibt also Möglichkeiten, damit umzugehen. Eine beliebte Methode ist die wesentliche Stärkung (oder Schlüsseldehnung). Im Grunde genommen wird ein Hash viele Male durchlaufen (in der Regel Tausende). Dies bewirkt zwei Dinge. Erstens verlangsamt es die Laufzeit des Hash-Algorithmus erheblich. Zweitens erhöht es, wenn es richtig implementiert wird (indem Eingabe und Salz bei jeder Iteration erneut eingegeben werden), die Entropie (den verfügbaren Speicherplatz) für die Ausgabe, wodurch die Wahrscheinlichkeit von Kollisionen verringert wird. Eine triviale Implementierung ist:

var hash = password + salt;
for (var i = 0; i < 5000; i++) {
    hash = sha512(hash + password + salt);
}

Es gibt andere, eher standardisierte Implementierungen wie PBKDF2 , BCrypt . Diese Technik wird jedoch von vielen sicherheitsrelevanten Systemen verwendet (z. B. PGP, WPA, Apache und OpenSSL).

Die Quintessenz, hash(password) ist nicht gut genug. hash(password + salt) ist besser, aber immer noch nicht gut genug... Verwenden Sie einen gestreckten Hash-Mechanismus, um Ihre Passwort-Hashes zu erzeugen...

Ein weiterer Hinweis zur trivialen Streckung

Die Ausgabe einer Hash-Funktion darf unter keinen Umständen direkt in die Hash-Funktion zurückgeführt werden. :

hash = sha512(password + salt); 
for (i = 0; i < 1000; i++) {
    hash = sha512(hash); // <-- Do NOT do this!
}

Der Grund dafür liegt in den Kollisionen. Bedenken Sie, dass es bei allen Hash-Funktionen zu Kollisionen kommt, weil der mögliche Ausgaberaum (die Anzahl der möglichen Ausgaben) kleiner ist als der Eingaberaum. Um zu sehen, warum das so ist, sehen wir uns an, was passiert. Gehen wir zunächst davon aus, dass die Wahrscheinlichkeit einer Kollision von 0,001 % besteht. sha1() (es ist viel niedriger als in der Realität, aber zu Demonstrationszwecken).

hash1 = sha1(password + salt);

Jetzt, hash1 hat eine Kollisionswahrscheinlichkeit von 0,001 %. Aber wenn wir die nächste hash2 = sha1(hash1); , alle Kollisionen von hash1 werden automatisch zu Kollisionen von hash2 . Damit liegt die Rate von Hash1 bei 0,001 %, und die 2. sha1() Anruf trägt dazu bei. Also jetzt, hash2 hat eine Kollisionswahrscheinlichkeit von 0,002 %. Das sind doppelt so viele Chancen! Jede Iteration fügt eine weitere 0.001% Chance einer Kollision mit dem Ergebnis. Bei 1000 Iterationen stieg die Kollisionswahrscheinlichkeit von trivialen 0,001 % auf 1 %. Jetzt ist die Verschlechterung linear, und die tatsächlichen Wahrscheinlichkeiten sind weit kleiner, aber der Effekt ist derselbe (eine Schätzung der Wahrscheinlichkeit eines einzelnen Zusammenstoßes mit md5 beträgt etwa 1/(2 128 ) oder 1/(3x10 38 ). Das scheint zwar wenig, aber dank der der Geburtstagsanschlag es ist nicht so klein, wie es scheint).

Stattdessen werden durch die erneute Eingabe von Salt und Kennwort jedes Mal erneut Daten in die Hash-Funktion eingebracht. So sind Kollisionen in einer bestimmten Runde keine Kollisionen mehr in der nächsten Runde. So:

hash = sha512(password + salt);
for (i = 0; i < 1000; i++) {
    hash = sha512(hash + password + salt);
}

Hat die gleiche Kollisionswahrscheinlichkeit wie der Eingeborene sha512 Funktion. Das ist es, was Sie wollen. Verwenden Sie das stattdessen.

169voto

Marc B Punkte 347897

Eine Hash-Funktion könnte man mit dem Backen eines Brotlaibes vergleichen. Man beginnt mit Eingaben (Mehl, Wasser, Hefe usw.) und erhält nach Anwendung der Hash-Funktion (Mischen + Backen) eine Ausgabe: einen Laib Brot.

Der umgekehrte Weg ist außerordentlich schwierig - man kann das Brot nicht wirklich in Mehl, Wasser und Hefe auftrennen - einiges davon ging während des Backvorgangs verloren, und man kann nie genau sagen, wie viel Wasser, Mehl oder Hefe für einen bestimmten Laib verwendet wurde, da diese Informationen durch die Hash-Funktion (auch bekannt als der Ofen) zerstört wurden.

Viele verschiedene Varianten von Inputs ergeben theoretisch identische Brote (z. B. ergeben 2 Tassen Wasser und 1 tsbp Hefe genau das gleiche Brot wie 2,1 Tassen Wasser und 0,9 tsbp Hefe), aber bei einem dieser Brote kann man nicht genau sagen, welche Kombination von Inputs es erzeugt hat.

Die Verschlüsselung hingegen könnte man als Tresorfach betrachten. Was immer man dort hineinlegt, kommt auch wieder heraus, solange man den Schlüssel besitzt, mit dem es ursprünglich verschlossen wurde. Es handelt sich um eine symmetrische Operation. Mit einem Schlüssel und einer bestimmten Eingabe erhält man eine bestimmte Ausgabe. Mit dieser Ausgabe und demselben Schlüssel erhält man die ursprüngliche Eingabe zurück. Es ist eine 1:1-Zuordnung.

51voto

mrsrinivas Punkte 30892

Grundlegende Übersicht über Hashing- und Verschlüsselungs-/Entschlüsselungstechniken sind.

Hashing:

Wenn Sie Hash jede einfacher Text wieder Sie kann nicht die gleiche Ebene bekommen Text aus gehashtem Text . Ganz einfach: Es ist ein einseitiger Prozess.

hashing


Verschlüsselung und Entschlüsselung:

Wenn Sie verschlüsseln jede einfacher Text mit einem Schlüssel wieder Sie kann denselben Klartext erhalten indem ich Entschlüsselung auf verschlüsselten Text mit gleichem (symetrischem)/unterschiedlichem (asymmetrischem) Schlüssel.

encryption and decryption


UPDATE : Um auf die in der bearbeiteten Frage genannten Punkte einzugehen.

1. Wann Hashes und wann Verschlüsselungen verwendet werden sollten

Hashing ist nützlich, wenn Sie jemandem eine Datei schicken wollen. Sie haben aber Angst, dass jemand anderes die Datei abfangen und verändern könnte. Also eine der Empfänger sicherstellen kann, dass es sich um die richtige Datei handelt, ist Sie den Hashwert öffentlich bekannt geben. Auf diese Weise kann der Empfänger den den Hashwert der empfangenen Datei berechnen und prüfen, ob sie mit dem Hashwert Wert übereinstimmt.

Verschlüsselung ist gut, wenn Sie jemandem eine Nachricht zukommen lassen wollen. Sie verschlüsseln die Nachricht mit einem Schlüssel und der Empfänger entschlüsselt sie mit der gleichen (oder vielleicht sogar einem anderen) Schlüssel, um die ursprüngliche Nachricht zurückzubekommen. Kredite


2. Was macht einen Hash- oder Verschlüsselungsalgorithmus anders (auf theoretisch-mathematischer Ebene), d.h. was macht Hashes unumkehrbar (ohne Hilfe eines Regenbogenbaums)

Grundsätzlich Hashing ist ein Operation, bei der Informationen verloren gehen, aber keine Verschlüsselung . Betrachten wir den Unterschied auf einfache mathematische Weise für unser leichtes Verständnis , natürlich haben beide viel kompliziertere mathematische Operationen mit Wiederholungen involviert

Verschlüsselung/Entschlüsselung (umkehrbar):

Zusatz :

4 + 3 = 7  

Dies lässt sich umkehren, indem man die Summe nimmt und eine der folgenden Zahlen abzieht Summanden

7 - 3 = 4     

Multiplikation :

4 * 5 = 20  

Dies lässt sich umkehren, indem man das Produkt nimmt und durch eine der Faktoren

20 / 4 = 5    

Hier könnten wir also annehmen, dass einer der Summanden/Faktoren ein Entschlüsselungsschlüssel ist und das Ergebnis (7,20) ein verschlüsselter Text ist.


Hashing (nicht umkehrbar):

Modulo-Division :

22 % 7 = 1   

Dies kann nicht rückgängig gemacht werden, da es keine Operation gibt, die man mit dem Quotienten und dem Dividenden durchführen kann, um den Divisor wiederherzustellen (oder umgekehrt).

Können Sie eine Operation finden, um die Stelle des '?' auszufüllen?

1  ?  7 = 22  
1  ?  22 = 7

Hash-Funktionen haben also die gleiche mathematische Qualität wie Modulo-Divisionen und verlieren die Information.

Kredite

47voto

Eric J. Punkte 143512

Verwenden Sie Hashes, wenn Sie nicht wollen, dass die ursprüngliche Eingabe wiederhergestellt werden kann, und Verschlüsselung, wenn Sie dies wollen.

Hashes nehmen eine Eingabe und wandeln sie in einige Bits um (in der Regel als Zahl, wie eine 32-Bit-Ganzzahl, 64-Bit-Ganzzahl usw.). Dieselbe Eingabe wird immer denselben Hash ergeben, aber man verliert dabei prinzipiell Informationen, so dass man die ursprüngliche Eingabe nicht zuverlässig reproduzieren kann (es gibt jedoch einige Einschränkungen).

Bei der Verschlüsselung bleiben grundsätzlich alle Informationen, die Sie in die Verschlüsselungsfunktion eingegeben haben, erhalten, es wird lediglich erschwert (im Idealfall unmöglich), die ursprüngliche Eingabe rückgängig zu machen, ohne im Besitz eines bestimmten Schlüssels zu sein.

Einfaches Beispiel für Hashing

Hier ein triviales Beispiel, um zu verstehen, warum Hashing (im allgemeinen Fall) nicht die ursprüngliche Eingabe wiederherstellen kann. Nehmen wir an, ich erzeuge einen 1-Bit-Hash. Meine Hash-Funktion nimmt eine Bit-Zeichenkette als Eingabe und setzt den Hash-Wert auf 1, wenn eine gerade Anzahl von Bits in der Eingabe-Zeichenkette gesetzt ist, und auf 0, wenn eine ungerade Anzahl gesetzt ist.

Beispiel:

Input    Hash
0010     0
0011     1
0110     1
1000     0

Beachten Sie, dass es viele Eingabewerte gibt, die einen Hash von 0 ergeben, und viele, die einen Hash von 1 ergeben. Wenn Sie wissen, dass der Hash 0 ist, können Sie nicht mit Sicherheit wissen, was die ursprüngliche Eingabe war.

Übrigens, dieser 1-Bit-Hash ist nicht gerade erfunden... sehen Sie sich das an Paritätsbit .

Einfaches Beispiel für Verschlüsselung

Man könnte einen Text verschlüsseln, indem man eine einfache Buchstabensubstitution verwendet, z. B. wenn die Eingabe A ist, schreibt man B. Wenn die Eingabe B ist, schreibt man C. Bis hin zum Ende des Alphabets, wo man, wenn die Eingabe Z ist, wieder A schreibt.

Input   Encrypted
CAT     DBU
ZOO     APP

Genau wie das einfache Hash-Beispiel hat diese Art der Verschlüsselung historisch verwendet worden .

29voto

Shiv Mohan Punkte 517

Mein Zweizeiler... Im Allgemeinen wollte der Interviewer die folgende Antwort.

Hashing ist eine Möglichkeit. Sie können Ihre Daten/Strings nicht aus einem Hash-Code konvertieren.

Die Verschlüsselung erfolgt in 2 Richtungen - Sie können die verschlüsselte Zeichenfolge wieder entschlüsseln, wenn Sie den Schlüssel bei sich haben.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X