Rivest-Shamir-Adleman Verschlüsselung (RSA)

Das RSA-Verschlüsselungsverfahren gehört zu den asymmetrischen Kryptosystemen (siehe auch Beitrag symmetrische- und asymmetrische Verschlüsselung). Es wurde im Jahr 1977 von den Kryptografen Ron Rivest, Adi Shamir und Leonard Adleman entwickelt. Es eignet sich neben der eigentlichen Verschlüsselung auch als Signaturverfahren. Der RSA-Algorithmus basiert auf dem Faktorisierungsproblem.

Funktionsweise RSA

Wie schon gesagt, beruht der RSA-Algorithmus auf dem Faktorisierungsproblem. Dies besagt, dass es mathematisch sehr schwierig ist, das Produkt zweier sehr großer Primzahlen wieder in die einzelnen Faktoren in annehmbarer Zeit zu zerlegen. Aktuell ist kein Faktorisierungverfahren bekannt, das die ganzzahligen Teiler einer Zahl effizient berechnen kann. Dies hat zur Folge, dass die beiden Faktoren nur durch probieren ermittelt werden können. Dies ist bei sehr großen Primzahlen sehr aufwendig und nimmt eine wenig praktikable Zeit in Anspruch. So lange kein effizientes Verfahren zur Primfaktorenzerlegung gefunden wird, gilt das RSA-Kryptosystem als sicher.

Vorgehensweise: Es werden zwei ausreichend große Primzahlen p und q zufällig gewählt, die geheim bleiben müssen. Lediglich das Produkt N ist bekannt. Anschließend konstruiert man zwei Exponenten, die in der Kryptographie als Schlüssel dienen. Einer davon ist öffentlich, der sogenannte Public Key (e), der andere privat – Private Key (d). Hierbei ist die Schlüssellänge variabel. Je länger der Schlüssel, desto sicherer ist das Verfahren.

Bei der Chiffrierung wird die zu übertragende Nachricht als Zahl m mit dem öffentlichen Schlüssel e und dem Produkt aus p und q zum Geheimtext c verschlüsselt.

c \equiv m^e \ mod \ \underbrace{p \cdot q}_N

Zur Entschlüsselung wird d benötigt:

m \equiv c^d \ mod \ \underbrace{p \cdot q}_N

d lässt sich nicht aus e berechnen, ohne die beiden Primzahlen p und q zu kennen.

Wichtig ist es, um es einem Angreifer unmöglich zu machen den privaten Schlüssel zu erraten, einen ausreichend großen Schlüssel zu wählen. Alle gängigen Verschlüsselungsalgorithmen sind in der Regel so konstruiert, dass die Rechenleistung moderner Computer nicht ausreichend ist, um in annehmbarer Zeit an den privaten Schlüssel durch einfaches Ausprobieren (vollständige Schlüsselsuche) zu gelangen.

Beispiel

Ein Beispiel der RSA-Verschlüsselung könnte wie folgt aussehen (der allgemeine Ablauf kann unter dem Beitrag Primzahlen nachgelesen werden):

  1. Wir wählen zuerst zwei Primzahlen p und q
    • Wert für p=23
    • Wert für q=31
  2. Ermittlung von N mit
    • N=p \cdot q=713 und berechne
    • \varphi(N) mit \varphi(N)=(23-1) \cdot (31-1) = 660
  3. Wähle dann e \in \{2,..., \varphi(N)-2 \} mit ggT(e, \varphi(N))=1 \Rightarrow 97
  4. Bestimme d mit e \cdot d \equiv 1 \ mod \ \varphi(N) = 313
  5. Damit sind N, e der öffentliche und N, d der private Schlüssel
    • N=713, e=97, d=313.

Mit obigen öffentlichem Schlüssel soll nun die Zahl 5 verschlüsselt und mit dem privatem Schlüssel wieder entschlüsselt werden.

563 \equiv 5^{97} \ mod \ 713 \Rightarrow die 563 ist somit unser Geheimtext c.

Der Geheimtext c soll nun wieder zum Klartext m entschlüsselt werden.

5 \equiv 563^{313} \ mod \ 713 \Rightarrow somit gelangen wir wieder zur 5 als Klartext m.

Untenstehndes Python-Programm beschreibt im wesentlichen den RSA-Algorithmus. Auf einen Test ob p und q Primzahlen sind, wurde aus Gründen der Einfachheit verzichtet. Wie ein solcher Test durchgeführt wird, kann in den Beiträgen „Fermat-Test“ und „Miller-Rabin-Test“ nachgelesen werden. Weiterführende Erklärungen zu den Bestandteilen von RSA sind zu finden unter: Euklidischer- und erweiterter Euklidischer Algorithmus sowie die Eulersche Phi-Funktion.

from random import randint

'''berechnet N'''
def berechneN(p,q):
    n = p * q
    return n

'''berechnet phi(N)'''
def berechnePhi(p,q):
    phi = (p - 1) * (q - 1)
    return phi

'''berechnet den ggT(e,phi(N))'''
def berechneGGT(e,phiN):
    while phiN!=0:
        e ,phiN = phiN, e % phiN
    return e

'''sucht ein zufaelliges e aus einer Liste'''
def sucheE(phiN):
    e = 2
    eListe = []
    egef = False
    while e <= phiN-2 and egef == False:
        if berechneGGT(e, phiN) == 1:
            eListe.append(e)
        e = e + 1
    return eListe

'''Alternative zur Ermittlung von e. Liefert erstes gefundenes e' --> schneller'''
def sucheEalter(phiN):
    e = 2
    eGef = e
    while e <= phiN-2:
        if berechneGGT(e, phiN) == 1:
            eGef = e
            break
        e = e + 1
    return eGef
        
'''Erweiterter Euklidischer Algorithmus zum Loesen der diophantischen Gleichung e*d+k*phi(n)=ggT(e,phi(n))=1'''
def extgcd(e, phiN):
    tmpphiN = phiN
    d, k, di, ki = 1, 0, 0, 1
    while phiN!=0:
        q=e//phiN
        e, phiN = phiN, e-q*phiN
        k, ki = ki, k-q*ki
        d, di = di, d-q*di
    if d < 0:
        d = d + tmpphiN
    return d

'''zufaelliges e aus Liste zurueck liefern'''   
def retEtmp(laenge):
    return randint(1, laenge)
    
    
'''Der Einfachheit halber, wird auf eine Pruefung, ob p und q Prim sind verzichtet --> Pruefung z.B. ueber Miller-Rabin-Test'''
if __name__ == '__main__':
    p = 23
    q = 31
    n = berechneN(p, q)
    phi = berechnePhi(p, q)
    eteilerf = sucheE(phi)
    laengeEListe = len(eteilerf)
    randE = retEtmp(laengeEListe-1)
    e = eteilerf[randE]
    d = extgcd(e,phi)
    
    print("N:", n)
    print("Phi(n):", phi)
    print("e (Public Key):", e)
    print("d (Private Key):", d)
    

Sicherheit RSA

Das RSA-Kryptoverfahren beruht, wie schon erwähnt darauf, dass es schwierig ist große Primzahlen in ihre Primfaktoren zu zerlegen. Die vollständige Schlüsselsuche ist beispielsweise bei einer Schlüssellänge von 256 Bit aussichtslos. Allerdings stellt die vollständige Schlüsselsuche nicht die beste Angriffsmethode auf das RSA-Verfahren dar. Gefährlicher ist ein Faktorisierungsangriff. Dieser ist zwar sehr aufwendig, kann aber dennoch zum Erfolg führen, wenn die verwendeten Primzahlen zu klein gewählt wurden.

Im Vergleich zum AES-Verfahren bietet das RSA-Kryptosystem eine größere Angriffsfläche. Die Sicherheit von RSA hängt im wesentlichen von der Implementierung und von der gewählten Schlüssellänge ab. Ist ein Verfahren sauber programmiert, dann hat der Angreifer nur noch die Möglichkeit durch bloßes Probieren aus dem öffenlichen Schlüssel den privaten Schlüssel abzuleiten. Im wesentlichen wird eine Schlüssellänge von 2.048 Bit oder besser von 4.096 Bit empfohlen.

Ein Problem bei dem asymmetrischen Verfahren RSA ist, dass die erforderlichen Schlüssellängen für eine sichere Verschlüsselung sehr lang sind. Sollten weitere Möglichkeiten für eine schnelllere Faktorisierung ermittelt werden, so ist eine sichere Verschlüsselung mit RSA auf Grung der Länge der benötigten Schlüssel nur schwer hanhabbar. Empfehlenswert sind daher EEC (Elliptic Curve Cryptography)-Verfahren mit elliptischen Kurven. Diese kommen mit einer geringeren Schlüssellänge aus um eine hohe Sicherheit zu gewährleisten.

Advanced Encryption Standard (AES)

Wie schon in dem Beitrag symmetrische- und asymmetrische Verschlüsselung erwähnt, handelt es sich bei der Verschlüsselungsmethode AES um ein symmetrisches Kryptosystem.

Der AES Verschlüsselungalgorithmus ist eine der sichersten und meistgenutzten Kryptoverfahren. Er wird zum Beispiel in den USA für Regierungsdokumente der höchsten Geheimhaltungsstufe verwendet.

Die Entwicklung von AES begann im Jahr 1997 als ein Nachfolger des in die Jahre gekommenen Verschlüsselungsstandards DES (Data Encryption Standard) gesucht wurde. Diese Suche dauerte vier Jahre und wurde offiziell vom Standardinstitut NIST ausgerufen. Unter einer Vielzahl von Bewerbern konnte sich letztenendes der von Joan Daemen und Vincent Rijmen entwickelte Rijndael-Algorithmus durchsetzten. Er überzeugte sowohl in Bezug auf Felxibilität, Sicherheit und Performance. 2001 wurde er schließlich offiziell als der neue Standard AES bekanntgegeben.

Die Funktionsweise von AES beruht auf einer Reihe von Byteersetzungen (Substitutionen), Verwürfelungen (Permutationen) und linearen Transformationen, die auf Datenblöcke von 16 Byte ausgeführt werden – hierauf beruht auch der Begriff Blockverschlüsselung. Diese Operationen werden mehrfach wiederholt, wobei in jeder dieser Runden ein individueller, aus dem Schlüssel berechneter Rundenschlüssel in die Berechnung mit einfließt. Wird nur ein einziges Bit im Schlüssel oder im Datenblock verändert, entsteht ein komplett anderer Chiffreblock.

Die Bezeichnungen AES-128, AES-192, AES-256 oder AES-512 beziehen sich auf die Länge des Schlüssels. Die Schlüssellängen des AES-Verschlüsselungsverfahren unterscheiden sich beträchtlich in der Länge des Schlüssels des DES-Kryptoverfahrens. Hier war nur eine 56-Bit Schlüssellänge möglich.

Um einen 192-Bit Schlüssel zu knacken würde ein moderner Supercomputer länger benötigen, als das geschätzte Alter des Universums. Bis heute ist für keine der AES-Varianten ein praktisch durchzuführender Angriff bekannt. AES gehört daher zu einem der meist genutzten Kryptosystemen bei Banken, Regierungen und High-Security-Systemen.

symmetrische- und asymmetrische Verschlüsselung

In der Kryptographie wird zwischen symmetrischen und asymmetrischen Kryptosystemen unterschieden. Diese unterscheiden sich vorallem in der Anzahl der verwendeten Schlüssel.

symmetrische Verschlüsselung

Beim symmetrischen Kryptoverfahren gibt es, anders als beim asymmetrischen Kryptoverfahren, nur einen Schlüssel. Dieser Schlüssel dient sowohl zur Ver- als auch zur Entschlüsselung. Dies bedeutet, falls Informationen ausgetauscht werden sollen, dass sowohl der Sender als auch der Empfänger im Besitz des Schlüssels sein müssen. Beim Sender ist dies natürlich kein Problem, da er bereits im Besitz des Schlüssels ist.

Beim Empfänger jedoch stellt sich die Frage, auf welchem Übertragungsweg der Schlüssel (Passwort, Key, …) sicher mitgeteilt oder übergeben werden kann. Dies ist auch zugleich ein Hauptnachteil der symmetrischen Verschlüsselung.

Beachtet werde muss, dass man symmetrische Kryptoverfahren in Block- und Stromchiffren unterteilen kann. Bei Stromchiffren wird z.B. der Klartext Zeiche für Zeichen verschlüsselt, während der Geheimtext auch wieder Zeichen für Zeichen entschlüsselt werden muss. Hingegen bei Blockchiffren, werden die Zeichen des Textes in feste Blockgrößen eingeteilt, sodass mehrere Zeichen in einem Schritt ver- bzw. entschlüsselt werden können.

Vorteile der symmetrischen Verschlüsselung sind:

  • einfaches Schlüsselmanagement, da nur ein Schlüssel zum ver- und entschlüsseln benötigt wird
  • verhältnismäßig hohe Geschwindigkeit für Ver- und Entschlüsselung, da Verfahren meist auf effizienten Operationen wie Bit-Shifts und logischen XOR-Operationen aufbauen

Nachteile der symmetrischen Verschlüsselung sind:

  • nur ein Schlüssel zur Ver- und Entschlüsselung, dieser darf nicht in unbefugte Hände geraten
  • wie schon erwähnt, muss der Schlüssel über einen sicheren Kommunikationskanal ausgetauscht werden
  • Anzahl der Schlüssel bezogen auf die Anzahl der Teilnehmer wächst quadratisch

Symmetrische Kryptoverfahren:

  • AES – Advanced Encryption Standard
  • DES – Data Encryption Standard (Schlüssellänge nur 56-Bit für mache Anwendungen nicht ausreichend sicher)
  • Trible DES – auch als TDES, 3DES oder DESede bezeichnet
  • IDEA – International Data Encryption Algorithm
  • Blowfish
  • Towfish
  • CAST-128, CAST-256
  • RC2, RC4, RC5, RC6
  • Fox

asymmetrische Verschlüsselung

Bei einem asymmetrischen Kryptosystem arbeitet man, anders als beim symmetrischen Kryptosystem, mit zwei unterschiedlichen Schlüsseln. Ein Schlüssel, der sogenannte Public Key, dient der reinen Verschlüsselung. Der zweite Schlüssel, der Private Key, dient der Entschlüsselung und sollte vom Eigentümer gut und sicher aufbewahrt werden.

Dieses Schlüsselpaar, der Public Key und der Private Key, hängt über einen mathematischen Algorithmus eng zusammen. Daten die mit dem öffentlichen Schlüssel verschlüsselt wurden, können nur mit dem privatem Schlüssel wieder entschlüsselt werden (siehe Abbildung unten). Der private Schlüssel muss daher vom Besitzer geheim gehalten werden.

Quelle: de.wikipedia.org

Ein konkreter Anwendungsfall könnte z. B. wie folgt aussehen: Will Benutzer A Daten verschlüsselt an Benutzer B übermitteln, so muss er ihm seinen öffentlichen Schlüssel übermitteln. Der private Schlüssel hingegen bleibt im Besitz von Benutzer A. Benutzer B verschlüsselt nun die Nachricht mit dem Public Key von Benutzer A und kann nun die geheime Nachricht an Benutzer A senden. Benutzer A kann nun wiederum die geheime Nachricht mit Hilfe seines privaten Schlüssels wieder entschlüsseln

Das Problem der asymmetrischen Verschlüsselung ist die Verteilung des Public Keys. In der Regel gesschieht die beim Erstkontakt mit dem Kommunikationspartner. Jedoch stellt sich hierbei die Frage, ob der vermutete Kommunikationspartner auch derjenige ist, für den er sich ausgibt.

Bei Asymmetrische Kryptosysteme geht es in der Regel darum, eine Funktion zu wählen, die sehr einfach zu berechenen ist, deren Umkehrung hingegen sich als sehr aufwendig gestaltet. Realisiert wird dies mit Modulo-Rechenfunktionen (siehe Kategorie Zahlentheorie). Diese sind teilweise recht einfach zu berechenen, jedoch gestaltet sich deren Umkehrung als sehr aufwendig. Solche Funktionen bezeichnet man auch als Einwegfunktionen. Funktionen bei denen sich die Umkehrung mit einer zusätzlichen Information abkürzen lässt, werden als Falltürfunktionen bezeichnet.

Ein Beispiel für eine Einwegfunktion ist der diskrete Logarithmus. Dieser kann sehr leicht berechnet werden. Umgekehrt ist es jedoch nicht in praktikabler Zeit möglich eine große Zahl zurüchzurechnen. Man bezeichnet dies als Diskreter-Logarithmus-Problem. Viele asymmetrische Verschlüsselungsverfahren beruhen darauf. Allerdings soll dies nicht bedeuten, dass nicht irgendwann ein Weg gefunden wird das Diskrete-Logarithmus-Problem zu lösen.

Beispiel:

Der diskrete Logarithmus beschreibt eine Kongruenz der Form: a^x \equiv m \ modulo \ p wobei x geheim ist.

a=2
m=396923
p=1419403
x \ ist \ geheim.

x lässt sich nur durch probieren ermitteln.

Untenstehender Python-Code liefert das erste Ergebnis durch einfaches probieren für den Wert x. Im Beispiel wird der Wert für x=26 schnell ermittelt, da die einzelnen Werte relativ klein gewählt wurden.

'''Phython-Programm zur Ermittlung von x'''
def calcX(a, m, p):
    i = 1
    while ((a**i % p) != (m % p)):
        i += 1
    return i
        
if __name__ == '__main__':
    a = 2
    m = 396923
    p = 1419403
    '''Berechnet a^i kongruent m modulo p'''
    diskLog = calcX(a, m, p)
    print("Wert fuer diskreten Logarithmus: ", diskLog)

Eine weitere Einwegfunktion ist das Multiplizieren von Primzahlen. Während die Multiplikationen für einen Computer kein Problem darstellt, so ist das Zurückrechnen d. h. das Zerlegen des Primzahlproduktes in die einzelnen Primfaktoren, bei sehr großen Primzahlen nicht in praktikabler Zeit möglich. Man spricht hierbei von Faktorisierung und in dem Zusammenhang vom Faktorisierungsproblem.

Beispiel:

Man berechnet 23 \cdot 31. Als Ergebnis erhält man 713. Um nun die 713 wieder in ihre einzelnen Faktoren zu zerlegen, gibt es hier nur einen Weg; man muss alle Möglichkeiten durchprobieren. Sind die Primzahlen sehr groß gewählt, so dauert dies sehr sehr lange.

Untenstehendes Pythonprogramm liefert einen möglichen Algorithmus zur Primfaktorzerlegung.

'''Python-Programm zur Primfaktorzerlegung'''
def primfaktor(zahl):
    primListe = []
    while zahl % 2 == 0:
        primListe.append(2)
        zahl = zahl // 2
    i = 2
    while i <=  zahl:
        if zahl % i == 0:
            primListe.append(i)
            zahl = zahl // i
            i = 2
        i += 1
    primListe.append(zahl)
    primListe.sort()
    if primListe[0] == 1:
        primListe.remove(1)
    return primListe  
    
if __name__ == '__main__':
    zahl = 713
    print(primfaktor(zahl))

Mögliche Angriffe auf asymmetrische Verschlüsselungsverfahren:

  • Public-Key-Only-Angriff: Ist der öffentliche Schlüssel bekannt, kann der Angreifer beliebigen Klartext verschlüsseln und beispielsweise mit bereits verschlüsselten Klartext vergleichen.
  • Chosen-Cipertext-Angriff: Der Angreifer schickt einen beliebigen Geheimtext an sein Ziel, um diesen entschlüsseln zu lassen.

Asymmetrische Kryptoverfahren:

Die bekanntesten asymmetrischen Kryptoverfahren sind das RSA- und das Diffie-Hellmann-Verfahren.