Clemens Schrimpe ist wieder zu Gast und hat sich vorgenommen, mir und euch etwas über Verschlüsselung im Netz beizubringen. Dabei wollen wir uns diesem Thema allgemeinverständlich nähern – eben “Crypto for the masses”. Besonderes Vorwissen oder mathematische Begabung sind nicht nötig; das habe ich persönlich für euch getestet. Es geht in dieser Episode erstmal um ein Grundverständnis der Konzepte zur Verschlüsselung. Mit dieser “Crypto-Werkzeugkiste” ausgestattet, gibt es die Fortsetzung in der nächsten Folge.
Freut euch aber jetzt auf den ersten launigen Teil unserer kleinen Crypto-Reihe, u.a. mit einem festgestellten Tatbestand des “Mangels der Ernstlichkeit” gem. §118 BGB und wir haben Hitler gesagt.
Shownotes
Baukasten
- Verschlüsselung / Encryption
- Signature
- Bestätigung: “non-repudation”
- Alice, Bob und Eve
- Man in the Middle = MitM
- Plain-text
- Cipher-Text
- Key / Schlüssel
- Brute-force
- side-channel attack
Zufall – very important to get crypo right!
Mathematik mit großen, ganzzahligen (“Integer”) Zahlen
- Multiplication
- Potenzierung (DE)
- Exponentiation
- Division / Modulusrechnung (DE)
- Prime number (EN) / Primzahlen (DE)
Cryptographic Hash Functions (EN) / Kryptographische Hashfunktion (DE)
“Text” rein → fixed-length hashvalue raus (immer der gleiche!)
Symmetric-key Algorithm (EN)
“Text” & 1 Schlüssel rein → Mumble raus → mit gleichem Schlüssel wieder → Text
- Advanced Encryption Standard (AES)
- AES instruction set bzw. bei Intel: AES new instruction (AES-NI)
- Stream Ciphers oder Block Ciphers
- Padding (cryptography)
- one-time pad
- Enigma
- AES Implementations (Applications)
Asymmetric key Algorithms – “Public key cryptography”
- Kummutativgesetz
- Digital Signature Algorithm (DSA), RSA (Rivest–Shamir–Adleman) , Elliptic Curve Cryptography (ECCxxx)
- Split-Key algorithms
Für manche als Einstieg um Systeme zu konfigurieren vll. interessant:
https://bettercrypto.org/
Gibts auch bei github, wer mitmachen will.
Derzeit sind die jedoch veraltet (kein TLSv1.3, keine djb crypto, neustes OS Ubuntu 16.04, neustes Openssl 1.0.1f)
Für HTTPS-Seiten interessant: https://www.ssllabs.com/
Die meinen, wie mir bisher auch bekannt war und hier bestätigt wurde, dass TLS Compression eher ne schlechte Idee ist.
Ich ziehe meinen Hut vor der großen Erklärgabe und -lust von Clemens. Dass bei der Kryptographie nur das meiste und nicht alles passt, finde ich ausgesprochen verzeihlich.
Trotzdem möchte ich einen Punkt kommentieren, der nicht nur ein bisschen falsch ist, sondern gefährlich falsch ist: Clemens hat darauf insistiert, dass es nach der Schlüsselgenerierung egal ist, welchen der beiden Schlüssel aus dem Paar man als privaten und welchen als öffentlichen verwendet.
F30 hat schon darauf hingewiesen, dass das bei anderen Verfahren als RSA nicht stimmen muss. Es stimmt auch für RSA nicht: Ja, beide Schlüssel bestehen aus Exponent und Modulus, ja, mit beiden werden dieselben Operationen durchgeführt. Und ja, wenn ich die beiden tausche, dann funktionieren Verschlüsselung und Signatur weiterhin – aber sie sind nicht mehr sicher!
Der Grund ist, dass der Exponent für den Public Key nicht zufällig gewählt wird, sondern man nimmt eine relativ kleine Primzahl, und zwar in aller Regel die 65537. Die hat nämlich eine sehr schöne binäre Struktur (10000000000000001), was dazu führt, dass das Rechnen damit sehr einfach und schnell geht. Der Exponent des privaten Schlüssel hat dagegen so viele Bits wie der Modulus, von denen ca. die Hälfte eine 1 ist. Deswegen sind Private-Key-Operationen (Signieren und Entschlüsseln) bei RSA um Größenordnungen aufwendiger als Public-Key-Operationen (Signatur validieren und Verschlüsseln).
Man könnte auch den Public Key zufällig wählen und den passenden Private Key dazu berechnen, dann könnte man sie gefahrlos tauschen – dann wären aber auch beide Seiten der Berechnung teuer, ohne dass es einen Sicherheitsgewinn bringen würde.
Dadurch, dass eigentlich immer derselbe Exponent für den Public Key genommen wird, ist er natürlich leicht erratbar. D.h., wenn ich in freier Wildbahn einen öffentlichen Schlüssel sehen würde, dessen Exponent nicht 65537 ist, sondern mehrere tausend Bit lang, dann würde ich mir überlegen, ob da vielleicht jemand Public und Private Key vertauscht hat. Und dann kann man ja mal versuchen, ob eine dafür verschlüsselte Nachricht nicht einfach mit Exponent 65537 entschlüsselt werden kann.
War mit wichtig. Ansonsten hoffe ich auf neue Folgen, insbesondere TLS! Aber auch die von Clemens angeregte Folge zu obsoleter Netzwerktechnik fände ich sehr geil.
Vielen Dank für die viele Arbeit bisher!
Danke für die Sendung, war interessant.
Was cool wäre wen ihr Ihr Howtos wie man manche Sachen implementiert mit reinpacken könntet
Danke für diesen super Podcast! Sehr gut erklärt für mich als Einsteiger…
Vorweg: vielen Dank für die tolle Folge! Da sie allerdings teilweise ein wenig methodisch inkorrekt war (und das ist nicht negativ gemeint!), hab ich noch einige Anmerkungen…
Bezüglich der ganzen Geschichte mit dem Zufall:
1. Kryptographisch sichere Zufallszahlen direkt nach dem Start und für beschränkte Systeme ist eigentlich ein gelöstes Problem. Man füttert den Zufallsgenerator einfach mit einem zufälligen Startwert von der Disk; beim Ausschalten speichert man dann den aktuellen Generatorstand als neuen Startwert. Geräte, die niemals neuen zufälligen Input erhalten, muss man halt beim Setup zufällig initialisieren. Der Haken an der Methode ist natürlich, dass der Seed geheim gehalten werden muss – deshalb will man wenn möglich schnellstens neuen Zufall einspeisen, um Vorhersagen zu verhindern.
2. Das Beispiel mit dem Salt bei Loginpasswörtern war unpassend – gerade der muss nämlich nicht zufällig, sondern “nur” einzigartig sein. Man könnte man bspw. auch einen Zähler nehmen. Ein zufälliger Salt ist halt bloß leichter zu realisieren ist als ein über alle Systeme garantiert synchronisierter Zähler.
Zur asymmetrischen Kryptographie:
1. Mit P und Q bezeichnet man bei RSA normalerweise die Primzahlen, die zur Schlüsselerzeugung verwendet werden; den öffentlichen Schlüssel bezeichnet man für gewöhnlich ganz normal als PK (public key) und SK (secret key).
2. Die Signatur ist keine “Verschlüsselung mit dem privaten Schlüssel”! Man nutzt bei RSA zwar zufällig die gleiche Operation, aber es handelt sich um zwei unterschiedliche Sachen mit vollkommen unterschiedlichen Anforderungen, weshalb selbst bei RSA das ganze Drumherum anders und nicht austauschbar ist. Bei praktisch allen anderen asymmetrischen Systemen unterscheiden sich Verschlüsselung- und Signaturverfahren massiv.
Meiner Ansicht nach ist dieses ganze “Signatur ist Verschlüsselung mit dem privaten Schlüssel” hochgradig irreführend und nicht hilfreich; ich plädiere dafür, die Signatur einfach eine Signatur sein zu lassen.
3. In der Regel sind Signatur und Verschlüsselung nicht kommutativ – wenn ich eine Nachricht signiere und dann verschlüssele, muss ich sie erst entschlüsseln bevor ich sie validieren kann.
4. In der Regel spricht man bei asymmetrischer Kryptographie heute nicht mehr von Verschlüsselung, sondern von Schlüsselaustausch. Das mit dem Verschlüsseln ist relativ RSA-spezifisch; mit anderen Verfahren kann man gar nicht direkt verschlüsseln, sondern “nur” ein Shared Secret generieren. Schlüsselaustausch passt dagegen für alle Verfahren.
5. So jung ist die ganze Elliptic-Curve-Cryptographie gar nicht; RSA wurde 1977 vorgestellt, die ersten ECC-Verfahren 1986 – das ist zwar schon einige Zeit später, aber gemessen daran, dass wir inzwischen 2018 haben…
Und weiter zur symmetrischen Kryptographie:
Ein zufälliger Schlüssel hat erstmal nichts mit einem One-Time-Pad zu tun. Das One-Time-Pad ist ein Verfahren, dass einen vollkommen zufälligen Einmalschlüssel, der genauso lang wie die Nachricht ist, eins zu eins mit der Nachricht XOR-verknüpft – ein zufälliger AES-Schlüssel ist dagegen nur ein zufälliger AES-Schlüssel.
Was das Thema Toleranz bei Implementierungen betrifft:
Toleranz ist gut, wo man sich vertraut oder wo es um nichts geht. Das heißt, wenn ich sage, “Der Server wird schon nichts böses senden” oder “Das Datenfeld ist eh unwichtig”, muss ich das nicht überprüfen und dem Server auf die Finger hauen. Sobald das aber nicht mehr gegeben ist, muss ich aufpassen und darf invalide Daten nicht mehr akzeptieren.
Und bei Krypto ist das halt normalerweise der Fall, weshalb es da nur ein Entweder-Oder gibt: Entweder, Algorithmus X ist bei meinem Bedrohungsszenario sicher oder er ist es nicht. Wenn er sicher ist, kann ich ihm vertrauen, wenn er es nicht ist, dann darf ich das logischerweise nicht – sonst kann ich das ganze mit der Krypto gleich sein lassen.
Ein gutes Beispiel für die Probleme, die sich aus übertriebener Toleranz ergeben, ist EFAIL: Der Angriff funktioniert nur, weil die E-Mail-Programme klaglos akzeptieren, dass eine Nachricht verschlüsselt, aber nicht oder nur teilweise signiert ist (für Ersteres gibt es in der Praxis kaum Gründe und das Zweite ist vollkommen absurd).
Natürlich neigen manche Leute dazu, das Bedrohungsszenario unrealistisch hoch einzuschätzen; aber im Kontext eines realistischen Bedrohungsszenarios ist Toleranz gegenüber unsicheren Sachen nicht sinnvoll. (Ich finde die Formulierung XY-Nazi übrigens echt unpassend; dazu steckt zu viel Übles hinter dem Wort “Nazi”.)
Und zu guter Letzt noch eine Anmerkung zu Perfect Forward Secrecy:
Das “perfect” bezieht sich darauf, dass für jede Verbindung wirklich ein eigenes Schlüsselpaar generiert wird (im Gegensatz zu bspw. einer täglichen Schlüsseländerung).
Das ganze liest sich jetzt vielleicht so, als ob ihr voll viel falsch gemacht hättet; aber wenn man bedenkt, was für ein hochkomplexes und vermintes Feld moderne Kryptographie ist, habt ihr euch echt verdammt gut geschlagen – ich bin mal auf die PKI-Folge gespannt 😊
Nun ja, leider habe ich mir beim Hören dieser Episode öfter an den Kopf fassen müssen. So geht es einem wohl, wenn man
MedienberichtePodcasts zu einem Thema hört, bei dem man selbst relativ viel Vorwissen mitbringt (auch wenn ich diesen Effekt bei bisherigen Folgen erfolgreich vermeiden konnte).Nüchtern betrachtet ist die Episode ja sicherlich für Einsteiger_innen gut brauchbar, in den Details aber gespickt mit Ungenauigkeiten und Hemdsärmeligkeiten. Clemens wollte ja von den pingeligen Mathematikern korrigiert werden, so einer bin ich nicht. Aber es gibt eben seit über 30 Jahren auch relevante Crypto-Forschung diesseits der mathematischen Grundlagen, deren Erkenntnisse viel zu selten in die Praxis zurück fließen (was sicherlich an beiden Seiten liegt, mit sowas wie TLS 1.3 wird es inzwischen besser).
Die Sicherheit des One-Time-Pads ist etwa keine Annahme, sondern informationstheoretisch beweisbar; klappt aber nur mit XOR und nicht mit anderen Elementaroperationen. Der Zusammenhang zwischen praktischen symmetrischen Algorithmen und dem One-Time-Pad wurde in der Folge etwas verwischt, tatsächlich bauen einige Algorithmen (Stream-Ciphers und Block-Ciphers in Modi wie CTR) eine Art One-Time-Pad mit kürzerem Schlüssel, andere funktionieren aber anders.
Dass man die Keys einer asymmetrische Verschlüsselung einfach umdreht für Signaturen, ist eine weit verbreitete Fehlannahme. Liegt wohl daran, dass das bei RSA so funktioniert und RSA sehr bekannt ist; im allgemeinen Fall stimmt es aber nicht. Man betrachte z.B. das ElGamal-Verschlüsselungsverfahren (das außer dem Erfinder nicht viel mit dem ElGamal-Signaturverfahren zu tun hat) und sehe, dass Public- und Private-Key schon allein eine ganz andere Struktur und Länge haben. Daraus bekommt man nicht so einfach Signaturen.
Dann die Sache mit der Austauschbarkeit der Algorithmen aus der “Legokiste”: Im Prinzip stimmt es natürlich, dass man innerhalb einer Klasse die Algorithmen beliebig austauschen kann, auch wenn die wenigsten echten Protokolle komplette Wahlfreiheit erlauben. Allerdings führt schon relativ große Freiheit zu unüberschaubar vielen Konfigurationen, mehr Code mit mehr Fehlern, schlechter Testbarkeit und vielen Randfällen. Downgrade-Attacken werden dadurch viel leichter. Deshalb geht man bei neueren Protokollen (z.B. TLS 1.3) eher dazu über, möglichst wenige statische Konfigurationen vorzusehen, da die praktischen Vorteile der Austauschbarkeit doch eher gering sind.
In eine ähnliche Richtung geht die Diskussion um das ebenfalls erwähnte “Be liberal in what you accept, and conservative in what you send” (Postel’s Law/Robustness Principle, RFC 1122): Der Ansatz ist auf den ersten Blick sinnvoll und vielleicht auch mitverantwortlich für den Erfolg des Internet. Allerdings führt auch er zu unüberschaubar vielen Randfällen, Inkompatibilitäten und damit Sicherheitsproblem. Ein Beispiel dafür sind die massiven Schwierigkeiten bei der Einführung von TLS 1.3. Daher gibt es aktuell auch einen RFC-Draft, der das Prinzip abschaffen will.
Obsolete Algorithmen nach wie vor zu implementieren und ggf. auf höherer Ebene zu behandeln, ist eine Option, allerdings ist das in der Praxis häufig ein UI-Problem. (Wie gibt man “schlechtere Sicherheit” an und was soll die User_in damit anfangen?) Auch Downgrade-Attacken sind damit leichter möglich und es gibt weniger Anreize, auf neuere Algorithmen umzusteigen. Nicht zuletzt deshalb müssen wir uns immer noch an genug Stellen mit sowas wie MD5 und SHA-1 herumschlagen.
In der Frage nach aktuellem Stand zu Verschlüsselung und Kompression gilt, was Pascal schreibt. Das ist nach wie vor ein prinzipielles Problem, dessen Auswirkungen man versucht, auf höherer Ebene zu beschränken.
Erwähnenswert wäre noch Authentifizierung mit Message Authentication Codes gewesen, da unauthentifizierte Verschlüsselung nach wie vor ein großes praktisches Problem ist und die Grundlage für bspw. EFAIL bildet.
So, genug des Klugscheißens. Wie gesagt, für Einsteiger_innen ist die Folge denke ich trotzdem geeignet, vielen Dank dafür!
Ich freue mich schon auf den nachfolgenden Podcast wo auf diesen Grundlagen aufgebaut wird :)
Super, endlich wieder Material! ;) Hoffentlich gibts bald auch mal was zu Tunneln, vll war das Intro ja ein Hinweis darauf?!
Fuer aktive Angriffe ist Mallory zustaendig, Eve ist auf die passiven spezialisiert (“eavesdropping”).
Zum Thema “Komprimierung und Verschlüsselung”: Das durchaus noch immer problematisch, und genau aus dem Grund ist z.B. bei TLS 1.3 die Möglichkeit zur Komprimierung (auf TLS-Ebene) auch komplett rausgeflogen. Bis TLS 1.2 ist zwar auf TLS-Ebene noch die Möglichkeit zur Komprimierung vorgesehen, allerdings haben alle modernen Clients (d.h. insbesondere Webbrowser) dieses Feature rausgeworfen, weil es unter bestimmten Vorraussetzungen sog. “Padding Oracle”-Angriffe auf die TLS-Verschlüsselung erlaubt, durch die ein Angreifer z.B. Cookies stehlen kann. Diese Angriff ist auch unter dem namen “CRIME” bekannt:
https://en.wikipedia.org/wiki/CRIME
Ein sehr ähnlicher Angriff, der nach dem gleichen Prinzip funktioniert, ist auch noch über die Möglichkeit zur komprimierten Datenübertragung auf HTTP-Ebene möglich. Diese Variante ist auch unter dem Namen “BREACH” bekannt:
https://en.wikipedia.org/wiki/BREACH_(security_exploit)
Beide Angriffe setzen voraus, dass ein Angreifer eigene Klartextdaten in die verschlüsselte HTTPS-Verbindung einschleusen kann, beispielsweise über ein Javascript, das von nem Werbenetzwerk geladen wird o.ä. Das Angriffsziel wird in der Praxis z.B. der Wert eines Session-Cookies sein, von dem der Webserver dem Browser über das sog. “HttpOnly-Flag” mitgeteilt hat, dass das Cookie nicht per JS auslesbar sein darf.
Das vom Angreifer eingeschleuste JS schickt immer wieder HTTPS-Anfragen an jenen Server, der das zu stehlende Cookie gesetzt hat, und fügt in seinen Request Daten ein, von denen er erraten will, ob sie auch im zu stehlenden Cookie-Wert vorkommen – das zu stehlene Cookie wird ja ohnehin bei jeder einzelnen dieser HTTPS-Anfragen mit übertragen. Der Angreifer schaut sich dann “von außen” die übertragene Datenmenge der verschlüsselten HTTPS-Verbindung an, und sieht, wenn die Datenmenge plötzlich kleiner ist als bei vorherigen Requests seines eingeschleusten Scripts. Diese veringerte Datenmenge bedeutet, dass die kompression irgendwo Daten “einsparen” konnte, was mit recht hoher Wahrscheinlichkeit darauf schließen lässt, dass ein Teil der vom Angreifer-Script gesendeten Daten übereingestimmt haben mit einem Teil der HTTP-Header der Anfrage (z.B. dem Cookie-Header). Wiederholt der Angreifer diesen Prozess oft genug, kann er dadurch irgendwann den vollständigen Wert des Cookies “erraten”.
Die Gegenmaßnahmen sehen wie folgt aus:
– Gegen CRIME wird die TLS-Komprimierung schlicht komplett abgeschaltet (moderne Browser implementieren das wie gesagt eh nicht mehr).
– Gegen BREACH kann man entweder HTTP-Komprimierung bei HTTPS-Verbindungen komplett abschalten (die einfache Variante), oder man muss seinen Webserver so konfigurieren, dass er nur statische Inhalte mit HTTP-Komprimierung ausliefert, aber weder dynamische Inhalte komprimiert ausliefert, noch komprimierte Requests annimmt.
Möglicherweise könnte man auch ähnliche Angriffe auf andere Protokolle durchführen die TLS verwenden (z.B. auf SMTP und IMAP/POP3, indem man dem Opfer eine große Zahl “Klartext-Erratungs”-Mails schickt, oder auf Jabber/XMPP mit entsprechenden Chatnachrichten), aber das hat meines Wissens noch niemand ausprobiert.
Daher gilt nach wie vor: Im Zweifelsfall lieber keine Kompression verwenden, außer wenn man sicherstellen kann, dass der Angreifer unter keinen Umständen eigenen Klartext in die komprimierte verschlüsselte Übertragung einschleusen kann. Das gilt übrigens unabhängig vom verwendeten Komprimierungsverfahren – ob für die Verschlüsselung zlib/deflate verwendet wird, oder z.B. brotli, spielt für den Angriff keine große Rolle – solange vom Angreifer eingeschleuste redundante Daten “wegkomprimiert” werden, bleibt die Verbindung angreifbar.
Die Eigenschaft von kryptographischen Hashes, dass bei ner “geringfügigen” Änderung des Eingangswertes/Klartextes ein “komplett anderer” Hash rauskommen muss (Minute 39 im Podcast), nennt man übrigens “Lawineneffekt, bzw. im englischen Sprachraum “avalanche effect”. Die gleiche Eigenschaft will man auch bei symmetrischen Blockchiffren (z.B. DES oder AES) haben.
https://de.wikipedia.org/wiki/Lawineneffekt_(Kryptographie)
Formell ist die Forderung i.d.R., dass wenn man *ein* beliebiges Bit der Eingangsdaten (Klartext) kippt/ändert, für *jedes* Bit der Ausgangsdaten (=Hash oder verschlüsselter Datenblock) die Wahrscheinlichkeit einer “Bitänderung” 50% betragen muss. Schon scheinbar kleine Abweichungen von diesen 50% können ausreichen, um nen Hash oder eine symmetrische Blockchiffre mit statistischen Verfahren angreifen zu können.