diff --git a/20230622/ad-20230622.txt b/20230622/ad-20230622.txt index fb190fbacceeb6193e3e858f620bdb15a48bc596..b21b376629071905e6d8017c5983b066b8e11f71 100644 --- a/20230622/ad-20230622.txt +++ b/20230622/ad-20230622.txt @@ -66,6 +66,11 @@ Beispiel: 1234513247519832645912938749631409478172389649182351 * 123406123785012784618723058163 = 152346494637670594525194299058889621869556846777469948747518602026934923166081213 +Dasselbe Beispiel, hexadezimal: + + 34CB03092F31959B6E7AD210A9A9FA6599F8A946E8F * 18EBF272F494AC4A21017A1F3 + = 523B0A443912908FD5D8D15AA87F9591614F7BF892D63356178422C9554C345E0BD + Stattdessen: schriftlich. --> O(log b) @@ -84,6 +89,19 @@ Beispiel: ---------- 1010100 +Das war BigEndian für den zweiten Operanden. +Übersichtlicher: LittleEndian. + + 14 * 6 = 84 + + 1110 * 110 + ---------- + 0 Vorteil: Ich muß den ersten Operanden + 1110 immer nur um 1 Bit weiter nach links schieben + 1110 (anstatt jedesmal von 0 um i Bits nach links) + ---111---- (In Assembler gibt es Bit-Shift um 1 mit Carry.) + 1010100 + Speicherplatzbedarf: log c = log a + log b --> Ich benötige für c höchstens so viele Ziffern, wie a und b gemeinsam haben. @@ -100,3 +118,133 @@ https://www.gnu.org/software/gnu-c-manual/gnu-c-manual.html#Bit-Shifting For both << and >>, if the second operand is greater than the bit-width of the first operand, or the second operand is negative, the behavior is undefined. + +Kryptographische Hash-Funktionen, 22.06.2023, 17:08:52 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Was ist das? + - gegeben: Daten, z.B. ein Text + - gesucht: eine "Prüfsumme", der Hash-Wert, die den Text eindeutig identifiziert + --> Es soll in der Praxis unmöglich sein, einen Text zu konstruieren, + der eine gegebenen Hash-Wert hat (z.B. den eines anderen Textes). + Wenn ich z.B. nur 1 Bit ändere, soll der Hash-Wert völlig anders sein. + - Anwendung: Authentisierung des Textes, insbesondere: kryptographische Signatur + +Wie funktioniert eine kryptographische Signatur? + - gegeben: Daten, z.B. ein Text + - gesucht: eine "Unterschrift", die klarstellt, von wem der Text stammt +Verfahren: + 1. Erstelle einen Hash-Wert des Textes. + Nun haben wir z.B. 256 Bit anstelle von 5 MB. + 2. Diesen Hash-Wert verschlüssele ich mit RSA + unter Verwendung des geheimen(!) Schlüssels. + ("Normal" wäre: _Ver_schlüsselung mit dem öffentlichen Schlüssel.) + 3. Überprüfung der Signatur: Entschlüsselung unter + Verwendung des öffenlichen(!) Schlüssels. + ("Normal" wäre: _Ent_schlüsselung mit dem geheimen Schlüssel.) +--> Alle können entschlüsseln, aber nur, wer den geheimen Schlüssel besitzt, + kann verschlüsseln. + 4. Wir erstellen selbst den Hash-Wert des Textes und vergleichen ihn + mit dem entschlüsselten. Bei Übereinstimmung: gültige Unterschrift + durch die Person, die den geheimen Schlüssel besitzt. + +Weitere Anwendung: Passwort-Authentifikation + - Wir speichern nicht das Passwort, sondern den Hash-Wert. + - Nach Eingabe eines Passworts bilden wir dessen Hash-Wert + und prüfen auf Übereinstimmung. + - Bei Übereinstimmung war das Passwort richtig. +--> Passwörter prüfen, ohne die Passwörter zu kennen. + +Damit das funktioniert, muß die Hash-Funktion "gut" sein: + - Unterschiedliche Texte müssen unterschiedliche Hash-Werte liefern. + Das ist mathematisch nicht möglich, aber: + Es sollte sehr unwahrscheinlich sein, durch Zufall oder Absicht + mehrere Texte mit demselben Hash-Wert zu bekommen. + - Es darf außerdem nicht möglich sein, aus dem Hash-Wert auf den Text zu schließen. + +Wie baut man eine Hash-Funktion? +Merkle-Damgård-Konstruktion: + - Blockgröße a (z.B. 256 Bit = 32 Bytes) + - Nachricht länger machen ("Padding") bis zu einem Vielfachen von a + - Nachricht in Blöcke m_i der Länge a aufteilen + - Wir verwenden eine Verschlüsselungsfunktion ("Kompressionsfunktion") f. + Dadurch soll die Ausgabe kleiner werden als die Eingabe. + - Wir starten mit einem Startvektor H_0, der irgendwelche Zufallszahlen enthält + (z.B.: Nachkommastellen von pi, Werte des Sinus für ganze Zahlen, ...) + - Wir iterieren: + + H_i := f (H_{i-1} || m_i) ("||" = "verkettet mit") + + Das bedeutet: + - Komprimiere den Startvektor. Dadurch wird er kürzer. + - Hänge den ersten Block der Nachricht an. + - Komprimiere das Ergebnis. Dadurch wird es wieder kürzer. + - Hänge den zweiten Block der Nachricht an. + - Komprimiere das Ergebnis. Dadurch wird es wieder kürzer. + - ... + - ... bis zum Ende der Nachricht. + --> Ergebnis: eine undefinierbare Matsche, die eindeutig dem Text zugeordnet werden kann. + (Alles ist deterministisch.) + + - Parallele: Mischen von Zutaten für die Zubereitung von Lebensmitteln + - Zutat 1 in die Schüssel. + - Umrühren. + - Zutat 2 dazu. + - Umrühren. + - Zutat 3 dazu. + - Umrühren. + - ... + - ... bis alle Zutaten in der Schüssel sind. + --> Ergebnis: eine undefinierbare, aber hoffentlich genießbare Matsche. + (Kenner können evtl. noch die Zutaten herausschmecken.) + + - Kompressionsalgorithmus: + Wir haben einen Ergebnisblock, eine Nachricht und ein (Block-)Verschlüsselungsverfahren. + - Ergebnisblock verschlüsseln, Nachrichtenblock als Schlüssel verwenden: + Davies-Meyer-Kompressionsfunktion + - Nachrichtenblock verschlüsseln, Ergebnisblock als Schlüssel verwenden: + Matyas–Meyer–Oseas-Kompressionsfunktion + - ... + +Was sind (Block-)Verschlüsselungsverfahren? + - deterministischer Pseudozufallszahlengenerator + (liefert für denselben Startwert dieselben Pseudozufallszahlen) + - Startwert = Schlüssel + +Einfaches Beispiel: (Stream-)Verschlüsselungsverfahren RC4 + + char S[256]: Tabelle mit 256 Zufallszahlen ("S-Box") + + char i; + char j; + + i++; + j += S[i]; + char k = S[j] + S[i]; // alles modulo 256 + Verschlüssele mit S[k]; // S[k] ist eine Pseudozufallszahl. Damit kann ich z.B. xodern. + vertausche S[i] mit S[j]; + nächster Buchstabe der Nachricht + +--> Die Nachricht wird schön durchmischt. + +Der Schlüssel ist gewissermaßen die S-Box. +(Genauer: Die S-Box wird mit Hilfe des Schlüssels initialisiert.) + +Achtung: Es ist sehr aufwendig, die Sicherheit eines Algorithmus' zu prüfen! +Bitte keine neuen ("noch sichereren, weil niemand sie kennt") Algorithmen ausdenken! +Nur seit vielen Jahren geprüfte Algorithmen sind sicher. + +Beispiel: Angriff auf AES +https://de.wikipedia.org/wiki/Advanced_Encryption_Standard#Schwächen_und_Angriffe + + Die Forscher Alex Biryukov und Dmitry Khovratovich veröffentlichten Mitte des + Jahres 2009 einen Angriff mit verwandtem Schlüssel[11] auf die AES-Varianten + mit 192 und 256 Bit Schlüssellänge. Dabei nutzten sie Schwächen in der + Schlüsselexpansion aus und konnten eine Komplexität von 2119 erreichen. Damit + ist die AES-Variante mit 256 Bit Schlüssellänge formal schwächer als die + Variante mit 128 Bit Schlüssellänge.[12] Ende 2009 wurde mit einer + Verbesserung des Angriffs eine Komplexität von nur noch 299,5 erreicht.[13] + Für die Praxis hat dieser Angriff jedoch wenig Relevanz, denn AES bleibt + weiterhin praktisch berechnungssicher.[13] + + --> AES-128 ist demnach sicherer als AES-256 + (mit effektiv nur 99.5 Bit Schlüssellänge)!