Ergänzungen zum Modul TGdI Vorlesung 7 – 10.07.2015 Themen Restklassenringe, Euklidischer Algorithmus, eulersche Phi-Funktion, diskrete Wurzeln und Logarithmen, Diffie-Hellmann Geheimnisse, RSA Verfahren. Literatur Zu GAP http://www.gap-system.org. 1 GAP – Teil 2 Vor einiger Zeit haben wir GAP kennen gelernt, um damit Operationen auf Automaten und regulären Sprachen durchzuführen. Nun wenden wir uns etwas mehr dem ursprünglichen Anwendungsgebiet von GAP zu, dem Rechnen in diskreten Zahlensystemen. Insbesondere soll es um Restklassenringe und die Anwendungen davon in der Kryptografie gehen. 1.1 Installation GAP ist auf den Pool-Rechnern bereits istalliert und kann mit dem Befehl gap in einem Terminal gestartet werden. Falls Sie Ihren eigenen Rechner verwenden erfolgt die Installation analog zum letzten mal. Das Packet FactInt ist im Pool bereits installiert und wird automatisch geladen. Einige Beispiele benutzen UNIX-Tools und OpenSSL um mit realen Schlüsseln zu arbeiten. Auf Linux-Systemen sollte alles verfügbar sein, unter Windows sind Installation und Verwendung aber gewöhnlich schwierig (eventuell hilft Cygwin). 1.2 Restklassenringe Alle folgenden Berechnungen werden in Restklassen- (auch Modulo-) Ringen stattfinden. GAP kann auf verschiedene Weisen damit hantieren: Zunächst gibt Funktionen direkt für Restklassenringe, im Manual unter der Überschrift ”14.5 Residue Class Rings ”. Ein erheblicher Teil der Funktionen, die wir verwenden werden, gehört aber zur Zahlentheorie (Kapitel 15); diese Funktionen sind meist am Suffix ”Mod” zu erkennen und rechnen mit normalen Zahlen, wobei die Operationen automatisch eine Modulo-Rechnung durchführen. Der Restklassenring Z/12Z, der beispielsweise alltägliche Uhrzeiten darstellen kann, kann in GAP mit der Funktion ZmodnZ erzeugt werden: r := ZmodnZ ( 1 2 ) ; Tatsächlich erzeugt die Funktion aber nicht den Restklassenring, sondern einen Ring, der sich dazu isomorph verhält, sprich auf Repräsentanten statt den unendlich großen Klassen rechnet. Dies erkennt man, wenn man die Elemente näher betrachtet: 1 Ergänzungen zum Modul TGdI Vorlesung 7 – 10.07.2015 e := Elements ( r ) ; Da wir bezüglich + eine zyklische Gruppe haben, kann man statt immer das gewünschte Element aus der Elementliste zu wählen einfach einen vielfachen des Erzeugers One verwenden. k-faches + des 1-Elementes ergibt dann das Element k: 10∗One ( r ) ; 10∗One ( r ) + 5∗One ( r ) ; 4∗One ( r ) ∗ 6∗One ( r ) ; Im letzten Beispiel tauchen besondere Elemente auf: zwei Elemente, beide nicht 0, ergeben im Produkt 0. Es handelt sich bei 4 und 6 also um Nullteiler. Die Multiplikationstabelle zeigt mehr solche Elemente: Display ( MultiplicationTable ( e ) ) ; Da die Tabelle aus Listenindizes besteht, wird die 0 des Rings als Element 1 der Elementliste dargestellt. Auch alle anderen Einträge sind eins höher als der Zahlenwert des Elements. Ein etwas anderes Bild ergibt sich, wenn für n eine Primzahl p gewählt wird. k := ZmodnZ ( 1 1 ) ; f := Elements ( k ) ; Display ( MultiplicationTable ( f ) ) ; Die Multiplikationstabelle zeigt nun ein regelmäßiges Muster. In keiner Zeile oder Spalte, abgesehen von der ersten, taucht ein Eintrag doppelt auf. Deshalb sind alle Elemente bis auf die 0 invertierbar, und die Elemente bilden mit der Multiplikation sogar eine Gruppe. Mit der additiven Gruppe wird daraus der Körper Z/pZ, in dem nachher die meisten Berechnungen stattfinden. Diese Inversen kann GAP ausgeben: i i i i i := I n v e r s e (7∗ One ( k ) ) ; = One ( k ) / 7 ; ∗ 7; ∗ 7 = 1∗One ( k ) ; ∗ 7 = 0∗One ( k ) ; Zur Berechnung dieser Inversen dient der erweiterte Euklidische Algorithmus. Dieser ist auch in GAP implementiert, allerdings für normale Zahlen. Wir wechseln nun also zu den zahlentheoretischen Funktionen. Gcdex ( 7 , 1 1 ) ; Die Ausgabe bedeutet, dass gcd = 7 * coeff1 + 11 * coeff2 gilt. Da der gcd 1 ist, und Vielfache von 11 bei Betrachtung mod 11 wegfallen, gilt 1 ≡ 7·coeff1, und coeff1 ist multiplikativ Invers zu 7. Auch der Quelltext zu Gcdex ist interessant: 2 Ergänzungen zum Modul TGdI Vorlesung 7 – 10.07.2015 D i s p l a y ( Gcdex ) ; Nun noch einmal kurz zurück zum Ring Z/nZ, wenn N keine Primzahl ist. Dann lässt sich mit der Multiplikation dennoch eine Gruppe bilden, in dem man nur die Elemente betrachtet, zu denen es Inverse gibt. Ein inverses Element existiert zu einer Zahl genau dann, wenn sie teilerfremd zu n ist (sonst liefert der Euklidische Algorithmus am Ende keine 1). Diese Zahlen kann GAP bestimmen: PrimeResidues ( 1 2 ) ; Phi ( 1 2 ) ; Die Anzahl solcher Zahlen ist die Eulersche ϕ-Funktion, die später eine besondere Bedeutung hat, denn in der Multiplikativen Gruppe gilt: aϕ(n) ≡ 1 mod n . Im Körper Z/pZ lassen sich nun allerlei Berechnungen durchführen. Potenzen lassen genau wie in den reellen Zahlen als mehrfache Multiplikation definieren, und auch die inversen Operationen dazu, die diskrete Wurzel (gesucht x so dass xa = m mod p) und der diskrete Logarithmus (gesucht x so dass ax = b mod p) existieren. GAP kann diese berechnen: PowerMod ( 5 , 2 , 1 1 ) ; RootMod ( 3 , 2 , 1 1 ) ; LogMod ( 3 , 5 , 1 1 ) ; # 5ˆ2 = 3 # 5 # 2 mod 11 mod 11 mod 11 Allerdings sind keine effizienten Verfahren bekannt. Also Verfahren die das Ergebnis garantiert wesentlich schneller liefern, als alle Elemente in der Struktur durch Proberechnung zu überprüfen. Diese Zahlen existieren nicht zwangsläufig ((p − 1)2 ≡ (−1)2 ≡ 12 mod p) und ihre Werte sind im Allgemeinen auch nicht aus der normalen Multiplikationstafel ablesbar. Die von GAP verwendeten Algorithmen verwenden eine Zerlegung in Primfaktoren, die vermutlich ebenfalls sehr schwer durchzuführen ist (für große Zahlen). Das Potenzieren von Zahlen in einem Restklassenkörper ist eine Operation, die leicht durchzuführen, aber vermutlich schwer rückgängig zu machen ist. Deshalb werden solche Operationen in der Kryptografie verwendet. Das diese Operationen schwer sind, heißt aber nur, das keine guten Verfahren bekannt sind; nicht das keine existieren. Die Sicherheit der darauf aufsetzenden Verschlüsselungsverfahren beruht auf der Hoffnung, dass niemand solche Verfahren entdeckt. 1.3 Diffie-Hellman Key Exchange Möchte man sich öffentlich auf irgend eine geheime Zahl zwischen 1 . . . p − 1 einigen ist das folgende Verfahren interessant. Das Verfahren von Whitfield Diffie, Mar3 Ergänzungen zum Modul TGdI Vorlesung 7 – 10.07.2015 tin Hellman und Ralph Merkle erlaubt zwei Kommunikationspartnern, wie üblich Alice und Bob, ein gemeinsames Geheimnis zu erzeugen, das auch der Angreifer Eve, der sämtliche Kommunikation mitbekommt, nicht bestimmen kann. Ein solches Geheimnis kann dann zum Beispiel als Schlüssel für eine weitere, symmetrische Verschlüsselung dienen. Das Verfahren nutzt die Tatsache das ca·b = cb·a gilt, aber das gemeinsame Geheimnis cab in Z/pZ nur sehr schwer aus ca oder cb alleine zu bestimmen ist. Alice und Bob bestimmen also zwei Zahlen a und b, die sie für sich behalten, veröffentlicht werden nur die gemeinsame Basis c, ca und cb , die alle auch Eve kennen darf. Alice kann, da sie a kennt, cab = (cb )a berechnen, analog Bob, nicht aber Eve. c := 4 2 ; p := 2 3 6 0 8 3 1 8 6 7 ; # Alice a := Random ( [ 2 ˆ 3 1 ca := PowerMod ( c , # Bob b := Random ( [ 2 ˆ 3 1 cb := PowerMod ( c , # e i n e wohl bekannte Zahl # e i n e Primzahl z w i s c h e n 2ˆ31 . . 2ˆ32 . . 2 ˆ 3 2 ] ) ; # s e h r geheim h a l t e n ! a, p); # geht an Bob . . 2 ˆ 3 2 ] ) ; # s e h r geheim h a l t e n ! b, p); # geht an A l i c e # Alice PowerMod ( cb , a , p ) ; # Bob PowerMod ( ca , b , p ) ; # Eve a := LogMod ( ca , c , p ) ; PowerMod ( cb , a , p ) ; # das gemeinsame Geheimnis # das gemeinsame Geheimnis # d i e s dauert h o f f e n t l i c h sehr lange . Mit Hilfe von GAP konnte Eve auch in diesem Beispiel noch das Geheimnis herausbekommen. Ausserdem war hilfreich, dass c keine Primitivwurzel war – sprich ord(c) < p − 1. Bei größeren Zahlen kann das Lößen durch Probeberechnungen aber schnell Stunden oder Jahre dauern. Wie ist es bei 2191 ≤ p ≤ 2192 ? p := 410188365063330646 9376667499754908362247825865098673035333; Hinweis: Berechnungen können durch drücken der Tastenkombination Strg+c abgebrochen wernden. 1.4 RSA Das RSA-Verfahren, benannt nach Ron Rivest, Adi Shamir und Leonard Adleman, ist ein asymmetrisches Verschlüsselungsverfahren. Asymmetrisch, da nur Bob verschlüsselte Botschaften an Alice schickt und diese leicht entschlüsseln kann. 4 Ergänzungen zum Modul TGdI Vorlesung 7 – 10.07.2015 Alice schickt den öffentlichen Schlüssel (n, e) an Bob, behält aber den geheimen Schlüssel (ϕ(n), s) für sich. In der Praxis wird e fast immer fest mit Wert 216 + 1 gewählt. Zur Verschlüsselung wird dabei die geheim zu haltende Botschaft x von Bob mit dem Exponent e potenziert mod n. Bob übertragt das Ergebnis y = xe mod n an Alice. Diese kann auch entschlüsseln, indem sie mit s = e−1 mod ϕ(n) potenziert. ϕ(n) = (p − 1) · (q − 1) und damit die Inverse zu e ist aber leicht zu bestimmen, wenn die Faktorisierung von n bekannt ist. Daher ist die Faktorisierung n = p · q das gut gehütete Geheimnis. Das Verfahren setzt also auf die Schwierigkeit der Berechnung von diskreten Wurzeln bzw. auf die Schwierigkeit n in die beiden Primfaktoren zu zerlegen. Die folgenden Befehle erstellen einen echten, aber nur 192-Bit starken, RSA-PublicKey, wie er z.B. bei ssh, https oder verschlüsselten eMails verwendet wurde. Auf einem System-Prompt: (nicht in GAP!) o p e n s s l g e n r s a −out weak . pem 192 o p e n s s l r s a −i n weak . pem −outform PEM −pubout > weak . pub Der öffentliche Schlüssel weak.pub enthält n und e in einem Base64-gepackten Format. Dekodieren lässt sich dieses mit einem Tool von OpenSSL: c a t weak . pub o p e n s s l a s n 1 p a r s e −i n f o r m PEM −i n weak . pub # Index des D a t e n s t r i n g s i s t 1 o p e n s s l a s n 1 p a r s e −i n f o r m PEM −i n weak . pub −s t r p a r s e 17 Es werden zwei hexadezimale Zahlen angezeigt: die kürzere ist der leicht erkennbare Exponent e = 1000116 , die längere der RSA-Modulus n. Um alle Botschaften nun ohne Kenntnis des privaten Schlüssels zu entschlüsseln, kann n faktorisiert werden. Da die Länge mit 192 Bit noch überschaubar ist, gelingt GAP dies in wenigen Minuten: x := NumbersString ( ”DAS PFERD FRISST BANANEN” , 2 ˆ 1 9 2 ) ; n := I n t H e x S t r i n g ( ” . . . ” ) ; # RSA Modulus e := I n t H e x S t r i n g ( ” . . . ” ) ; # RSA Exponent y := PowerMod ( x [ 1 ] , e , n ) ; # v e r s c h l u e s s e l t e Botschaft Sind die Faktoren, und damit effektiv der private Schlüssel, gefunden, so gelingt Eve die Entschlüsselung schnell. pq := F a c t o r s ( n ) ; # s e h r aufwaendig ! p h i n := ( pq [ 1 ] − 1 ) ∗ ( pq [ 2 ] − 1 ) ; # = Phi ( n ) s := 1/ e mod p h i n ; broken := PowerMod ( y , s , n ) ; # Geheime B o t s c h a f t a l s Zahl . . . StringNumbers ( [ broken ] , 2 ˆ 1 9 2 ) ; # . . . und a l s Text 5 Ergänzungen zum Modul TGdI Vorlesung 7 – 10.07.2015 Aufgaben 1. Versuchen Sie eine geheime RSA Nachricht mit der diskreten Wurzel zu entschlüsseln. 6