Die einfachste Erklärung, wie symmetrische Verschlüsselungsalgorithmen heute funktionieren

(Ich habe auf Twitter einen Thread mit einer sehr coolen Erklärung symmetrischer Chiffren gefunden. Er wurde von Colm MacCárthaigh, einem der Hauptverantwortlichen von Apache, geschrieben. Ich habe Colm um Erlaubnis zum Übersetzen gebeten, er stimmte freundlicherweise zu.)


Ich werde Ihnen im Klartext erklären, was passiert, wenn Daten verschlüsselt werden. Ich hoffe, dass ohne die Mystik und die komplexen Dinge, die von Kryptographen erfunden wurden.


Symmetrische Verschlüsselung ist also genau das, was wir in den meisten Fällen verwenden, wenn wir eine Reihe von Daten verschlüsseln möchten. Ihr Browser sendet und empfängt Daten mit symmetrischer Verschlüsselung. Wenn Sie Dateien oder eine Festplatte verschlüsseln, funktioniert in diesem Fall auch die symmetrische Verschlüsselung. iMessage, Signal, WhatsApp - alle verwenden symmetrische Verschlüsselung für die Sicherheit Ihrer Korrespondenz.


Wenn Sie der Meinung sind, dass beim Verschlüsseln die Daten gemischt werden, sodass niemand sie ohne Schlüssel lesen kann, so wie es tatsächlich geschieht.


Hier ist ein einfaches Beispiel. Angenommen, ich habe eine Ovaltine-Zeichenfolge und möchte sie verschlüsseln. Ich könnte rot13 verwenden - Caesars sehr einfache Chiffre der alten Schule, die einen runden Tanz aus Buchstaben macht, bei denen a und z Hände halten, und jeden Buchstaben durch einen anderen Buchstaben des Alphabets ersetzt, der 13 Zeichen aus dem ersetzten Buchstaben besteht. Somit wird "O" zu "B" und "v" wird zu "i", wodurch "Ovaltine" zu "Binygvar" wird. Das ist natürlich nicht sehr sicher. Dies ist ein naives Beispiel, das sehr leicht zu knacken ist, da der Angreifer herausfinden kann, welcher Buchstabe am häufigsten gefunden wird (normalerweise im Originaltext „e“) und die verbleibenden Buchstaben auf diese Weise finden kann.


Jetzt können Sie sich vorstellen, dass es schwierigere Möglichkeiten geben sollte, die Buchstaben zu „mischen“. Zum Beispiel ein komplexes Schema, bei dem "a" zu "p" geht, bei erneuter Verschlüsselung jedoch zu "f". Vielleicht beginnt dieses Schema sogar manchmal, "a" mit zwei Buchstaben zu verschlüsseln, zum Beispiel "jd" oder etwas anderes. Somit kann dieses komplizierte Schema "Ovaltine" in die Zeichenfolge "FGyswDmweeRq" verschlüsseln (beachten Sie, dass es länger geworden ist). In der Vergangenheit gab es Verschlüsselungsalgorithmen, die auf ähnliche Weise funktionierten, aber so funktioniert moderne Verschlüsselung überhaupt nicht.


Anstatt Buchstaben zu "mischen", nimmt die moderne Verschlüsselung Ihre geheime Zeichenfolge und kombiniert sie kunstvoll mit zufälligen Daten. Dies ähnelt rot13 nur in zwei Aspekten: Verschlüsselung und Entschlüsselung sind im Wesentlichen der gleiche Vorgang, und alles geschieht „an Ort und Stelle“. Haben Sie tatsächlich bemerkt, dass rot13 sowohl ein Verschlüsselungs- als auch ein Entschlüsselungsalgorithmus ist? rot13 (Ovaltine) -> Binygvar, rot13 (Binygvar) -> Ovaltine. Ich glaube, dass dies eine sehr schöne Symmetrie bei der symmetrischen Verschlüsselung ist. Aber zurück zu unserem Thema. Der Trick ist, dass wir die bitweise XOR-Operation verwenden. In Kryptographie, formaler Logik und Code können XOR-Programme unterschiedlich bezeichnet werden, aber ich werde eine Notation verwenden, mit der Sie höchstwahrscheinlich vertraut sind. Es sieht so aus: ^.


XOR steht für "exklusives ODER". Dies ist ein Operator (oder eine Funktion, wenn Sie dies bevorzugen), der zwei Argumente akzeptiert und das Ergebnis zurückgibt. A ^ B = C. Dieser Operator wird "bitweise" genannt, da er für einander entsprechende Bits gilt. Wenn A und B Bytes sind, können wir annehmen, dass A ^ B = C im Wesentlichen 8 verschiedene Operationen sind, die gleichzeitig auftreten. ^ vergleicht das erste Bit A und das erste Bit B und setzt dann das Ergebnis in das erste Bit C. Es wiederholt dasselbe noch sieben Mal für die verbleibenden Bits. Die Regeln sind einfach: Wenn das Bit von A "1" ODER das Bit von B "1" ist, setzen wir das entsprechende Bit C auf "1", aber nur, wenn "A" und "B" nicht gleichzeitig "1" sind. Dies ist der exklusive Teil. Hier ist eine Old-School-Wahrheitstabelle:


A|B|C 0|0|0 1|0|1 0|1|1 1|1|0 

Das Coolste an XOR ist, dass es wie rot13 aussieht. Wir können es zur Ver- und Entschlüsselung verwenden. Ich werde dies anhand eines einfachen Beispiels zeigen. Stellen wir uns vor, wir möchten die übliche Nummer "3" verschlüsseln und unser Verschlüsselungsschlüssel ist eine andere Nummer "7". Somit ist 3 ^ 7 = 4. Das heißt, das Verschlüsselungsergebnis ist "4". Lassen Sie uns nun die Nummer entschlüsseln. Ich mache einfach noch einmal das Gleiche: 4 ^ 7 = 3. Nehmen Sie eine beliebige Zahl oder Daten, und es wird immer funktionieren - XOR kann sich immer selbst entschlüsseln.


Stück für Stück - so verschlüsseln und entschlüsseln wir Daten tatsächlich, es gibt kein Mischen, nur XOR-ing. Der schwierige Teil besteht darin, Daten zu finden, auf die wir XOR anwenden können. Ein Ansatz besteht darin, einen großen Teil der geheimen Daten zur Hand zu nehmen und als zweites Argument für XOR zu verwenden. In diesem Fall müssen alle Teilnehmer, die verschlüsselte Daten übertragen, denselben Satz geheimer Daten für die Ver- und Entschlüsselung verwenden. Und es wird funktionieren. Es stimmt, es gibt mehrere Probleme.


Das erste Problem. Geheime Daten sollten zufällig erscheinen. Sie können keinen Text aus einem Buch oder Ähnlichem entnehmen. Alle Muster werden in den verschlüsselten Daten angezeigt. Genau das hat die alliierten Streitkräfte im Zweiten Weltkrieg überlegen gemacht.


Das zweite Problem. Sie können vertrauliche Daten nicht wiederverwenden, da Muster wieder angezeigt werden. Sie müssen also irgendwie große Teile geheimer Daten für alle bereitstellen, die sie benötigen, wie z. B. das One-Time-Pad. Das ist zu schwer.


Bei der modernen Verschlüsselung „generieren“ wir die geheimen Daten, die wir benötigen, aus kleinen Schlüsseln. Diese Schlüssel sind viel einfacher zu tragen und zu schützen. Dies sind symmetrische Verschlüsselungsalgorithmen - Schemata zur deterministischen Erzeugung zufälliger Daten aus einem Schlüssel. Der Teil über „Determinismus“ ist sehr wichtig: Zwei Personen mit demselben Schlüssel müssen absolut denselben Datensatz generieren, sonst können sie sich nicht verstehen. Sie haben wahrscheinlich von solchen Algorithmen gehört: AES, 3DES, DES, RC4, ChaCha20. Sie alle machen es.


Es stellt sich heraus, dass das mathematische Problem der Erzeugung eines zufälligen Datenstroms (in dem es keine Muster in vorhersehbarer Form gibt) unter Verwendung des Schlüssels sehr schwierig ist. Von dieser Liste gelten heute nur AES und ChaCha20 als sicher. Andere Algorithmen wurden gehackt: Die Leute konnten sie vorhersagen. Darüber hinaus hat AES einen leicht getrübten Ruf, da Kryptographen Folgendes sagen:


AES ist der wichtigste und am häufigsten analysierte Verschlüsselungsalgorithmus. Absolut Gold Standard! : dark_sunglasses:

Gleichzeitig fügen sie hinzu:


AES-Implementierungen in Software (nicht in Hardware) sind entweder unsicher oder langsam und manchmal nicht sicher und langsam. Es wurde nicht unter Berücksichtigung der Tatsache entwickelt, dass es mithilfe der Cache-Analyse gehackt werden kann. : Gesichtspalme:

Seien Sie nicht zu ängstlich, wenn Ihnen dies nicht klar ist. Die Hauptidee ist folgende: AES ist aus mathematischer Sicht großartig, aber bei der Softwareimplementierung sehr kompliziert. Aber keine Sorge - wir haben fast immer AES-Unterstützung auf Hardwareebene (eine Liste aller Prozessoren mit AES-Hardwareunterstützung finden Sie hier https://en.wikipedia.org/wiki/AES_instruction_set , - Anmerkung des Übersetzers).


Wie dem auch sei, wir fahren fort ... Wie funktionieren diese Algorithmen tatsächlich? Wie können wir einen Schlüssel nehmen und sicher einen zufälligen Datenstrom erzeugen? Ich werde die Dinge hier etwas vereinfachen und mit Blöcken beginnen.


Diese Algorithmen empfangen drei Parameter am Eingang und geben den Chiffretext am Ausgang aus. Eingabeparameter - ein Schlüssel, verschlüsselter Text und ... Überraschung - etwas Seltsames namens "Initialisierungsvektor" (Initialisierungsvektor, IV).


 AES(key, IV, plaintext) -> encrypted_data. 

Der Schlüssel und IV werden miteinander kombiniert, um eine Reihe von "Startbedingungen" für den Algorithmus zu erstellen. Dies ähnelt dem anfänglichen Tauschen oder Mischen von Kacheln in einem Scrabble-Spiel. Die gleiche Kombination von Schlüssel und IV schafft immer die gleichen Startbedingungen. Sie fragen, warum brauchten wir dann überhaupt IV? Wir benötigen eine IV, damit wir mehrere Nachrichten mit demselben Schlüssel verschlüsseln können. Ohne IV wäre jeder generierte Datenstrom derselbe, und das ist schlecht. Dies würde gegen eine der Regeln verstoßen, über die wir zuvor gesprochen haben: Wir können nicht dieselben Daten für die Verschlüsselung wiederverwenden. Wir brauchen also eine IV, um das Ergebnis zu mischen. Aber im Gegensatz zu Schlüssel IV kann es öffentlich sein.


Wenn Sie also eine Nachricht verschlüsseln und an jemanden senden, können Sie auch hinzufügen: "Hey, hier ist die IV, die ich verwendet habe." Es ist immer noch wichtig, dass wir die Kombination aus Schlüssel und IV nicht wiederverwenden, da sie uns wiederholte zufällige Daten liefern würden. Es gibt zwei Möglichkeiten, um diese Bedingung zu erreichen: 1) IV ist eine Art Zähler, den wir mit jeder neuen Nachricht erhöhen. 2) IV wird zufällig generiert, obwohl es einen ziemlich großen Wert hat, sodass wir uns keine großen Sorgen um Kollisionen machen müssen. Wie dem auch sei, ich erwähnte, dass ich über Blöcke sprechen werde.


Schlüssel und IV werden so „gemischt“ oder kombiniert, dass eine Reihe von Startbedingungen erstellt wird. Diese Bedingungen sind eigentlich der anfängliche „Block“ von Zufallsdaten. Die Länge dieses Blocks beträgt 128 Bit für AES128, 256 Bit für AES256 und 512 Bit für ChaCha20. Und hier manifestiert sich die wahre Magie und Individualität eines bestimmten Verschlüsselungsalgorithmus. Tatsächlich liegt ihre Essenz darin, wie die Folge von Blöcken erzeugt wird und wie jeder Block seinen Nachbarn zugeordnet wird. Die Beziehung zwischen diesen Blöcken bleibt auch für diejenigen vorhersehbar, die keinen Schlüssel haben.


Ich werde nicht näher auf die Funktionsweise dieser Algorithmen eingehen, aber wenn Sie mehr wissen möchten, empfehle ich Ihnen, dieses Thema mit den linearen Kongruenzgeneratoren (LCG) zu untersuchen. LCG ist eine Funktion, die "kreisförmige" Datenblöcke auf zufällige und sich nicht wiederholende Weise erstellt. Dann werfen Sie einen Blick auf Feistel-Netzwerke, die nächste Stufe der LCG-Entwicklung. Beschäftigen Sie sich dann mit S-Boxen und sehen Sie sich an, wie der Salsa20 Interlacing im ChaCha20-Algorithmus erzeugt. All dies ist viel günstiger als Sie vielleicht denken!


Wir wissen jetzt, wie ein zufälliger Datenstrom mit Text kombiniert werden kann, um ihn zu verschlüsseln und zu entschlüsseln, und wir sind bereits ein wenig damit beschäftigt, wie diese zufälligen Datenströme erstellt werden. Ist das nicht alles was wir brauchen? Für die Festplattenverschlüsselung ist das wirklich fast alles. Wir können jeden Block oder Sektor des Speichers mit einem Schlüssel und IV verschlüsseln, die von der "Position" auf der Festplatte erhalten werden können. Somit können wir jeden Datenblock jederzeit irgendwo auf der Festplatte entschlüsseln, solange wir den Schlüssel haben. Aber es gibt ein Problem ... jemand kann unsere verschlüsselten Daten ruinieren. Wenn ich den Wert eines Bytes ändere, auch wenn ich keinen Schlüssel habe, können wir den Block am Ende nicht entschlüsseln. Und es gibt keinen Schutz gegen diese Art von Interferenz. Beim Senden von Nachrichten und Daten über das Netzwerk wird dies noch kritischer. Wir möchten nicht, dass jemand unsere übermittelten Daten verderbt. Wir müssen also eine Integritätsprüfung hinzufügen! Dazu gibt es mehrere Schemata.


HMAC, GCM und Poly1305 sind die gängigsten modernen Integritätsprüfungsschemata. Diese Algorithmen funktionieren grundsätzlich so: Sie werden mit Daten und einem weiteren Schlüssel (dem sogenannten Integritätsschlüssel) geliefert. Nach den Berechnungen geben sie den MAC (Nachrichtenauthentifizierungscode) oder das Tag aus, das wiederum nur ein weiteres Datenelement ist, das als Signatur fungiert.


Aus Gründen der Verschlüsselung und des Schutzes kann unser Schema daher folgendermaßen aussehen:


 AES(key, IV, "Ovaltine") -> encrypted_output HMAC(key, encrypted_output) -> MAC 

und dann per Kabel senden wir:


 IV | encrypted_output | MAC 

Zur Entschlüsselung überprüfen wir den MAC, generieren ihn erneut und vergleichen das Ergebnis mit dem empfangenen MAC. Anschließend entschlüsseln wir die Daten. Es gibt interne Unterschiede bei der Generierung dieser Signaturen durch HMAC, GCM und Poly1305, aber Sie müssen sich darüber keine Sorgen machen. Bisher ist diese Kombination von Operationen normalerweise in eine Funktion namens "AEAD" (Authenticated Encryption with Additional Data) eingebunden. Unter der Haube macht sie alles, worüber ich vorher gesprochen habe:


 AEAD(key, IV, plaintext, additional_data) -> IV_encrypted_data_MAC 

Ein Stück namens "Additional_Data" sind nur Daten, mit denen Sie sicherstellen können, dass der sendende Teilnehmer über diese Daten verfügt, obwohl sie nicht an ihn gesendet wurden. Es ist wie bei Metadaten, die Zugriffsrechte festlegen. Oft wird dieses Feld leer gelassen.


Trotzdem können Sie Probleme mit AEAD haben, wenn Sie dieselbe IV verwenden. Das ist schlecht! Es gibt Versuche, diese Situation zu verbessern: Mein Kollege, der Shay heißt, arbeitet an einem coolen SIV-Schema, das einen zusätzlichen Schutz gegen dieses Problem bietet. Wenn Sie jedoch eine eindeutige IV verwenden, ist die moderne Verschlüsselung sehr sicher. Das heißt, Sie können den Chiffretext in der New York Times veröffentlichen, und niemand kann ihn knacken. Die Chiffre bleibt auch dann unzugänglich, wenn „ein“ Teil des Textes bekannt ist. Beispielsweise ist in Internetprotokollen eine große Textmenge bekannt. HTTP-Server reagieren immer gleich und die ersten Bytes sind immer bekannt. Aber diese Tatsache spielt überhaupt keine Rolle - es wird dem Angreifer nicht helfen, einen einzigen Teil der verbleibenden Daten herauszufinden ... Wir haben seit dem Zweiten Weltkrieg einen langen Weg zurückgelegt.


Aber es gibt Angriffe, die funktionieren! Wenn Sie Daten über ein Netzwerk senden und jemand die Zeit und Größe von Nachrichten verfolgt, können verschlüsselte Daten mithilfe der Verkehrsanalyse geknackt werden.


Bild


Lassen Sie uns zuerst die Länge herausfinden. Offensichtlich ist die Länge kein verstecktes Merkmal. Dies ist normal, wenn Sie versuchen, Ihr Passwort oder Ihre Kreditkartennummer irgendwo in der Mitte der Nachricht zu schützen. Kein großes Problem. Dies bedeutet jedoch, dass möglicherweise jeder die Art des von Ihnen eingereichten Inhalts bestimmen kann. Ein einfaches Beispiel: Wenn Sie ein GIF mit einem Messenger senden und die Größe dieses Bildes eindeutig ist, schlägt der Angreifer, der Ihre Daten abfängt, möglicherweise vor, welches GIF gerade gesendet wurde. Es gibt schwierigere Versionen dieses Angriffs für Google Maps, Netflix, Wikipedia usw. Um sich vor diesem Angriff zu schützen, können Sie die gesendeten Nachrichten mit zusätzlichen Bytes "beenden", sodass alle gesendeten Nachrichten unabhängig von der Länge gleich lang sind. Die in militärischen Netzwerken verwendete Verschlüsselung „beendet“ den Datenverkehr immer mit zusätzlichen Daten, dh für den Interceptor sieht er immer gleich aus! Ein weiteres Problem mit der Länge besteht darin, dass der Angreifer selbst die kleinsten Geheimnisse herausfinden kann, wenn Sie die Komprimierung verwenden und dem Angreifer die Möglichkeit geben, einen beliebigen Teil des Inhalts auf der Seite zu ändern, die der Benutzer sieht. Suchen Sie nach einem Angriff namens CRIME. Sie ist wunderschön und beängstigend.


Ich sagte auch, dass das andere Problem das Timing ist. Offensichtlich ist die Sendezeit jeder Nachricht eine offene Information. Könnte dies ein Problem sein? Vielleicht! Wenn Sie beispielsweise jedes Mal, wenn Sie eine Taste drücken, eine Nachricht senden, ist es trivial, mithilfe der Zeitanalyse herauszufinden, was genau gedruckt wird. Cool! Ein weiteres Beispiel ist VOIP. Wenn Ihre Anrufanwendung Daten nur sendet, wenn Personen sprechen, jedoch nicht während der Stille, reicht dies aus, um 70% der englischen Sprache wiederherzustellen. Nur aus Stille. Beängstigend cool.


Diese Beispiele sind nur die Spitze des Eisbergs. Selbst wenn Sie Verschlüsselungsalgorithmen und -schemata verwenden, die sich seit 80 Jahren verbessern, gibt es immer noch Lücken, die zum Knacken der Sicherheit verwendet werden können. Deshalb ist es wertvoll, darüber Bescheid zu wissen!


Wie dem auch sei, dies ist die Erklärungsebene, auf die ich jetzt eingehen möchte, aber wir haben die wichtigsten Dinge in Betracht gezogen, die wir wissen müssen. Wenn Sie bis zu diesem Punkt gelesen haben - danke! Sie sollten jetzt besser verstehen, was während der Verschlüsselung passiert und worauf Sie achten müssen.


Fühlen Sie sich frei, Fragen zu stellen.


Die Übersetzung wird unter der CC BY-NC-SA 4.0-Lizenz veröffentlicht

Source: https://habr.com/ru/post/de443050/


All Articles