HSG

Aktuelle Seite: HSG/Fächer/Informatik/Kryptologie

Aufgabe 0

Informiere dich bei wikipedia ber die XOR-Verknüpfung und erläutere folgendes Beispiel.

>>> 3^5
6
>>> bin(3)
'0b11'
>>> bin(5)
'0b101'

Was ergibt wohl 10^7? Wie ist x zu wählen, damit 10^x == 42 richtig ist?

Aufgabe 1

Informiere dich bei wikipedia über das One-Time-Pad-Verfahren.

Aufgabe 2

Entschlüssele mit Hilfe von CrypTool und dem Schlüssel 20051001ABCDEF33 den mit dem XOR-Verfahren verschlüsselten Geheimtext kiqsߨ—G .

Cryptool ist hier tatsächlich kryptisch. Zwar kann man für den Schlüssel schnell eine Codierung der Bytes als Hex-Ziffern-Paar erahnen,

Schlüsseleingabe

doch die Zeichenfolge 'kiqsߨ—G' macht mehr Kopfzerbrechen. Nach einigem Probieren auf der Python-Shell scheint die Windows-Codepage 1252 richtig zu sein.

def hex2bytes(h):
    """
    gibt zu einer Folge von Hex-Ziffer-Paaren (str) die zugehoerige Bytefolge
    (bytes) zurueck
    """
    n = len(h)
    return bytes([int(h[2*i]+h[2*i+1],16) for i in range(n//2)])

Shell

>>> t = 'kiqsߨ—G'
>>> b = bytes(t,'cp1252')
>>> b
b'kiqs\xdf\xa8\x97G'
>>> s = hex2bytes('20051001ABCDEF33')
>>> s
b' \x05\x10\x01\xab\xcd\xef3'

Aufgabe 3

GUI zu tool0 Überprüfe CrypTool, indem du z.B. die ASCII-Darstellung des Zeichens 'k' mit dem Bitmuster 2016 = 0010 00002 xor-verknüpfst und das Ergebnis als Zeichen darstellst. Das kleine Tool Tool0 (tool0.zip) kann dabei als Hilfe benutzt werden. Wer Python hat, braucht das Tool nicht. Kontrolliere so mindestens drei Zeichen.

>>> b = ord('k')
>>> s = int('20',16)
>>> b^s
75
>>> chr(75)
'K'

Aufgabe 4

Erstelle in Python einen kleinen funktionalen 'OTP-Werkzeugkasten' otp.py. Bedenke die Codierungsproblematik und die Möglichkeit, Bytes mit base64 für ältere Protokolle 'transportabel' zu machen. Erledige Aufgabe 2 zum Test mit Python.

Warum ist one-time-pad sicher?

Mit Hilfe eines Rollenspiel-Würfels wurde die Folge 'D93BCAD5DB' erwürfelt und damit der Schlüssel s erstellt. Warum darf man nicht einen Pseudo-Zufallszahlengenerator benutzen?

>>> s = hex2bytes('D93BCAD5DB')
>>> s
b'\xd9;\xca\xd5\xdb'

Mit dem Schlüssel s wurde der String 'minus' verschlüsselt und probeweise wieder entschlüsselt.

>>> b = bytes('minus','ascii')
>>> c = crypt(b,s)
>>> c
b'\xb4R\xa4\xa0\xa8'
>>> crypt(c,s)
b'minus'

Könnte es sein, dass es einen Schlüssel s1 gibt, der aus dem gleichen Chiffrat den Klartext 'plus ' macht?

>>> s1
b'\xc4>\xd1\xd3\x88'
>>> crypt(c,s1)
b'plus '

Das verblüfft! Das Chiffrat c ergibt mit dem Schlüssel s den Klartext 'minus' und mit dem Schlüssel s1 den Klartext 'plus '.

Mit welchem Schlüssel erhält man 'gut ', mit welchem 'boese' ? Wie weiß der Codebreaker, dass er den richtigen Schlüssel hat?

Pseudozufallszahlen

Was bewirkt random.seed ?

>>> import random
>>> [random.randint(0,255) for i in range(20)]
[206, 178, 87, 39, 245, 86, 23, 24, 216, 154, 206, 186, 137, 249, 96, 141, 212, 158, 220, 147]
>>> [random.randint(0,255) for i in range(20)]
[180, 11, 58, 74, 20, 59, 25, 71, 162, 93, 94, 53, 68, 239, 165, 155, 43, 186, 41, 97]
>>> random.seed(42)
>>> [random.randint(0,255) for i in range(20)]
[163, 6, 70, 57, 188, 173, 228, 22, 108, 7, 55, 129, 6, 50, 166, 139, 56, 150, 207, 1]
>>> random.seed(42)
>>> s = [random.randint(0,255) for i in range(20)]
>>> s
[163, 6, 70, 57, 188, 173, 228, 22, 108, 7, 55, 129, 6, 50, 166, 139, 56, 150, 207, 1]

Kryptographisch sicherer Zufallszahlengenerator - wikipedia

20 Bytes auf einer Webseite?

Wenn man 20 Bytes auf einer Webseite darstellen will, so hat man verschiedene Möglichkeiten:

86 Zeichen:

[163, 6, 70, 57, 188, 173, 228, 22, 108, 7, 55, 129, 6, 50, 166, 139, 56, 150, 207, 1]

67 Zeichen:

[163,6,70,57,188,173,228,22,108,7,55,129,6,50,166,139,56,150,207,1]

62 Zeichen

\xa3\x06F9\xbc\xad\xe4\x16l\x077\x81\x062\xa6\x8b8\x96\xcf\x01

40 Zeichen

>>> b = [163,6,70,57,188,173,228,22,108,7,55,129,6,50,166,139,56,150,207,1]
>>> ''.join([hex(z)[2:].zfill(2) for z in b])
'a3064639bcade4166c0737810632a68b3896cf01'

28 Zeichen

owZGObyt5BZsBzeBBjKmiziWzwE=

20 Zeichen, behauptet Python bei diesem String, übrigens: chr(163) = '£'

£\x06F9¼\xadä\x16l\x077\x81\x062¦\x8b8\x96Ï\x01

Nachgezählt sind es 47 Zeichen. Wie überredet man Python richtig zu zählen?

Welche Darstellung gewinnt den Wettbewerb? Warum?

base64 mit Python

>>> s
b'\xa3\x06F9\xbc\xad\xe4\x16l\x077\x81\x062\xa6\x8b8\x96\xcf\x01'
>>> import base64
>>> e = base64.b64encode(s)
>>> e
b'owZGObyt5BZsBzeBBjKmiziWzwE='
>>> d = base64.b64decode(e)
>>> d
b'\xa3\x06F9\xbc\xad\xe4\x16l\x077\x81\x062\xa6\x8b8\x96\xcf\x01'
>>> list(d)
[163, 6, 70, 57, 188, 173, 228, 22, 108, 7, 55, 129, 6, 50, 166, 139, 56, 150, 207, 1]

Siehe auch: ASCII Armor

Aufgabe 5

Welche Bytes sind durch kiqsߨ—G dargestellt? Untersuche den String mit Python. Welche Probleme birgt eine solche Darstellung?

Ein Chiffrat und zwei Schlüssel

Chiffrat, c

l/0CB6IfW1T43If0zdk0xZG+iMHxSmkfRn45BfcPF3AAz+zVC+5hJN3lwuCYlBpHFmR30agZ4yGvO2N8zhXQxS9238M3X1njmClEQanGtJBH4Y7PBfY8KSa7rWPUZaz+H+baB4LEg6dGE1bNpoYBQ8C6WjFU4pBvWcoKkSgWw+4TFrHzUNdWdgPafhhT73mvk0Ac4ngBqNM1hIt/Vk4uNuOMulcjdoh+ezdME3epUYjeTbyd2KGcazh/KEhBrwydICSiu93jBwq728T4LsHInwinUWu4/nVIpm243Tna1rwU43UgixwRk0FVvrFWFgChr7UXZoDxz9zrS5YE/bx7PUzIFs6Xe+RjLqiNQyRmQYP3Bu+tK0tFp8fGnNlgc26/hInGYnZWi8I722LOnNmdrkX3db2FnJ8BjTuTknOUVQ/reUd/GpK5Z/AuvqmyXKp/sw87IPxwz8orwGH2QaLH9/OLDV7jGgSKmAkXKSQfbDLQ+ajKDN5EGk7V6VcwZCupnAtDwu4ZlJmMbntSdlmNWjjkdJIpf/NEkoNaIGGmpFh3nFSb46jZv8TT9sT0xbaeLQp6g4nM5AJfDGUexGYb4uBRJs5KeyXHwfqe4ydNG5T6piT8wLp5bE9THuhHfjhwv0kisFLsZ1ZKIHof4iCOkGBBV8OxHoaGhoK8flVmc/iwe/yLYbv7SJTWVUkd+b1F7lzlgE2MldU+qI0dTR+hBI2HVaHnkJU76bIA7s4pIOwNlJM2rnBW3UFJmHxkgwDB/wNGtVCYP4f47DOON2z5D8BZ0z77EZMMEz5lVszjankv67vIC1wRbmIj3A68rfFhiDj/1jE3D1igWoYuV4FLat8CrD6C1Y4Z3Dwk/KoH0tCdtHx47QhhSiA81A4b5/Y1j6+B5fq7TM3spJ9Xbm7o2B1XkPS+zDo0WSceFlKk9tK9u4wGS4YrhqVoteA4VgwB4p0B/WmikdwkGBuqItDc6cQtEBmM5ZB1wKkjkkux3m9trcxFu8k3UoYwl9EKmL8ezi241q2EZpk6psKXG2zXsTkGyHje3yYTfvXXG4FZ+/GBQvqGuipcxbeRmVDHOpg96Ww2twH/hp2Vn0EF/4f/XUPkqqzqPVyCliKRvkSeGQwFxt6OC13+yXS6bFYYDlftq+J6NHja9i8L+GYqOnKy2qpruPoJxej2WLsyommBwnru1+v9iJ7htIUNNdH1NwjqfnLPvKe6nQ+QPu72dlu5cbmYmbOj7RyGT6k94ozBmrFPG0WuyqtqWZyvbSdt0g8xT6ZsVOLtvirwY0pYMCe9Tw0l045R6qu4FCt1TPk15+C4VoJrbNxC43px/gBttEWeBXQOauZUV59yE3hI7qbpMYijU8G2K4yUwDHWTT8g4C+tMkDTVR+CzxyryzC6S/aO85b2Fzt1GzFKTyT+Fwe4WZFeSp2JwcTbAVEfioWc/bncH8lz+g==

Schlüssel 1, s1

zrJXJ/VWFxjYms66iflgjdSe3JO0CzpKFDsZR6JdXjVE76WbK7opYf2jjq/XxjoIUEQ28eBQp2XqdUM/j0OV5WY4/4IXDBygymwQYf+H+NwCuK6JRKQcb3T04EOALeneTKObJ8OKx4cAUgTt4NRODuDyFXwRwsQgeYxD32w2irozT/6mcIQeOVaWOjgSoTrn3BI8qzYh75J5yM4wGG5sd7qs+xlnVtw/MHJsRz/scdyMDP/W+O3ZKnw2Zg9h/EPIdGz1/o63J0v3lIq/DpWA2ij1FC+YrDwe4z+YnmuVhe80tz1lq0xQwBJ1//8SNkPu4eFeKNW0nPynAtFMqfAiHRuNRZq3NKJDfefYF2xGAMWjQ72NbQIT4ueL1ZUlIE7my9zmNT8ax+Jonifu3fnP4Qa8Ve7N3c9EyRvf2zjRdU7LOgYxVN33R6Rm+4nwHfgt9kMbb7pQm4Jik0G1AOyJuL2rXRGqVFDZuExPaGdLIGvwreedTYwASW6Up3dxNnnmyysVg6JV0cCsOTIGPnnZEmqhMbJ+PqcBwMUbbC31hAw/2XTNqvyY8+ScuIHUjOW+eUI/o8SFoEYTSUVRiiM7sbQQaIpqNGvnlbLbw2EBWsDa9Gu/i5o4OG8HVq1nKncgnwZkkAakInYMYTZTwmHA1EAUBIr/WabHpsHzMwUnIKuQN7PEKpu/HdH2GwZPrfVltxOwoBrF2Zke+8hYbV6BV9nSG/Wi1LVvu/dFzol7b7tE2tQW4T52nGEH2S42zFfhs0YC8hW4fcKwpX3KFzixTpR5h2y+VLNFQB4xHonDLzd7ufqGSBkxOi0DiEb5jbIg3n3fknhwLw3wetJmEqENJpBN/h7Dm8o5hXNx3P1Onpy98jU2qSgsEwBzmEo7tLN0r+zJoKnvbIul6NMSKk6/kUkfsLPxgH4UCm5SQBf21pPz/6xECsF4puoulaJ9F1lVq9tUsUnx0Ix0UFL4Z4P8qIppMFzBoMI0jO1wsh/5mz0ojY0X/ul2HtV/t4JF1fo+jWLrguHdRspq74HSSEyW/30miViNi3RSMLKSO8YLvrTPYqnS+34JgJfe33CGdLhopyd4+Faxptra22FRt8LfCRGh6/+/bxmi33Gx5wvLS18lh5DKKxTenj3pJHZBQQLN5q0ocViWo2xA2DJiezySk/5L+qhGkK++DJt/50nMm1qinq24qNag56VPcJS7F0u/LCGK+Ifp1EHTe86/Vh32JPfcufr3zV3KA4l0rKyV0vAbOwbij+o4ENLoTWgj8k1+GOMidKu+8mu+J2oZfWjzCF5x89oZr4v6W2UwH9l0qaSYBck+IJARwzU33lQl5gDbJSFALKkGA8o8UiwNvYa+eceDG4DyC8jdhXX2D3pmr33oEhSbEEaijFP+h3SaGbPapsS4N3M6VnRqGG2qXyfsEdQXGL3PjpaPVB9aqsDeuPeZWpM2qA==

Schlüssel 2, s2

1pAiRsx5Ojqf/PSXpaxS5dbR/LXRAgByKxtVJYJhc1BFvYiwJc40SrnFpon9tF81cgFXpslrw1ZshxAI7mC+oQ8auqZFc3mW9k1kJNrmw/E1weima4VITFSbzBayRcibbcaObuei5pxmZjiphuJkMeD9P1gnlrAoNr5+9Fs2sI17YdSRJLJ2F3a8Xnw2gln48jNvhwoviIZb4Ks4OTpaFpD8yDZAHrJePkRsZBLbNe3+AdX+sNW9S00RTGgk3CzqQVbGm5GKZGLP9eStQKXo2GfTJUvLnx1khgnZHqb6st1nwzlJ6HRlsyYgypEhd3KPj/F2RvOSp7WOL7ZDksgPHSipZe7bEocLWoj7LEpGJeaFJqnERTgxwrWo9apABgDbpOenDBgi7uJfuhHu0LD+xjHXIdzivOpv6Rv3+xa0E2aFCjMaaPzQFNBg38raKIRf924bV50Cq+pKtRLWAMCimZereDCHOknl6m5yRwR7CUDwnNq5eLtkTi+yx3dlCk+J22Q3ts5q5OvtDRNoVhz+ek+BBvZMX5Yt/OZ6ZgTV0D1X5iPykMux2qrzkqGa5eH/Xnkf8efgxHcxaEV6rQM7kYU4BqsjFQWSr477kVQuc/2fwgSGt9MKDyc2cMgjG1ZQ6ChRwzeeCXhqZBs/j0Ht+BQkd4TeavKm4uvZXhMDAIzVW4nlBZuIK/y/MC09ndw2zguE8z7p5/VLxvl4Pz/FYf+nE8SU5PAbn91uzqpMTcxa9eBFywJ2Hv0r/Q5E52Wz30UjxiT9EaetgleuUh/ZaKUqsFaaebNtf00KeOy2BB0PrNS8f3x/DwxNqGucyZgEqH6apUVSLxDJN+tLO69rLr4i21/wsa54qU8EvchivLS9wRIczUUOOEdZui5/goQV7sHlgIjebJmNw7F3OwCM+Fo45ICev0pGOER2LHLhhfLO2uFrJ+ML9cwL3cBcN38htfxyjgzQsalKbH7YArS5hORleXThgPxVoccD8C7CsQEJyL4gmwqhIPJV5f0q/N7dUQ3Vt8OkAvhJhpbldA+81Fdj6Au7t0M9XqC5f6E8iNHmJ4nl0ks05db96j/pGs1TjUxx2HWLpvP08S9xmqebPDDE/t6FXjfn+Eex+zb6fCAls7DqKzmXrFTpDTt1YiKDzMIeUQr6oU54iwNYGhzTtMQf3dpst8i7Pd5AjEnUrB7OkISJ/L6S1e0hFbWU9JfKGwHv29LOvXjxTMDWIzXdUf737ceDnmz0LspV2KyE6ZEjejbdr4sOMPmPKFUJty9QOsALMYqI0Aq3ESsrEFLTKy1uoe8knoeYcEoGbIpchIiYNOcYDbEnz1oEkGRN0jfrZhx6CIcmMr8w0Nw9g8PFEezCc6TfRaz+pVa6JFxIhV2NXCGwPT/xqnXFrkKaCoT609CEYlgdbxE+PUWZcifNN/V+IvzrpOSoZDhx7+u8mNC7eqcWlA==

Aufgabe 6

Decodiere c, s1 und s2 zu Bytefolgen und entschlüssele mit Hilfe von otp.py c einmal mit s1 und einmal mit s2.

Aufgabe 7

Teste das Beispiel, bei dem ein harmlos aussehender Text eine ganz andere Bedeutung hat. Kann man mit dem Verfahren allgemein geheimen Nachrichten ein harmloses Aussehen verleihen?

g = b'H\xc3\xa4nschen klein ging allein in die weite Welt hinein '
s = b'\x05\xaa\xd0\x1a\x04\x0c\x0b\rB\x00\\VUY\x06\x00\x05\x0c\t\x0eN\x0f\x18L\x01\x0c\x1c\x00(\x00G\x16\x00\x03FW\x04\x04T\tI9\x0e\t\x1a\x00.\x05\xad\xd9\x0e\x0bL'

Exkurs, Aufgabe 8

Stellt folgende Bytefolge einen utf8 -codierten String dar?

[163, 6, 70, 57, 188, 173, 228, 22, 108, 7, 55, 129, 6, 50, 166, 139, 56, 150, 207, 1]

Experimente auf der Shell

>>> lb = [163, 6, 70, 57, 188, 173, 228, 22, 108, 7, 55, 129, 6, 50, 166, 139, 56, 150, 207, 1]
>>> b = bytes(lb)
>>> b
b'\xa3\x06F9\xbc\xad\xe4\x16l\x077\x81\x062\xa6\x8b8\x96\xcf\x01'
>>> [bin(z)[2:].zfill(8) for z in b]
['10100011', '00000110', '01000110', '00111001', '10111100', '10101101', '11100100', '00010110', '01101100', '00000111', '00110111', '10000001', '00000110', '00110010', '10100110', '10001011', '00111000', '10010110', '11001111', '00000001']
>>> str(b,'utf8')
Traceback (most recent call last):
  File "<pyshell#6>", line 1, in <module>
    str(b,'utf8')
  File "/usr/lib/python3.1/encodings/utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeDecodeError: 'utf8' codec can't decode byte 0xa3 in position 0: invalid start byte

Schon das erste Byte macht Probleme. Am Anfang '10' erkennen wir ein Folgebyte, dh. der Anfang des Zeichens fehlt. Jetzt folgen drei 1-Byte-Zeichen, das erkennt man an der führenden Null. 1-Byte-Zeichen stimmen mit ASCII überein. Man wird neugierig, ob das auch für die nicht druckbaren Steuerzeichen gilt. (Lass dir chr(0) bis chr(31) anzeigen! Schaue dir www.unicode.org/charts/PDF/U0000.pdf an.) Die zwei folgenden Bytes sind wieder ein Folgebytes ohne Startbytes. Dann hat der Zufall ein Startbyte erzeugt. Die führenden Bits '1110' stehen für den Anfang eines 3-Byte-Zeichnens. Was sofort wieder zu Fehlern führt, denn es folgen 4 1-Byte-Zeichen. Eine weitere Durchsicht ergibt, dass kein einziges Mehrbytezeichen korrekt vorkommt. Wie groß wird wohl die Wahrscheinlichkeit sein, dass 20 zufällige Bytes eine gültige utf8-Zeichenfolge darstellen?

Damit man nicht nur Fehler sieht, soll der String 'A߀' utf8-codiert und analysiert werden:

>>> s = 'A߀'
>>> b = bytes(s,'utf8')
>>> b
b'A\xc3\x9f\xe2\x82\xac'
>>> [bin(z)[2:].zfill(8) for z in b]
['01000001', '11000011', '10011111', '11100010', '10000010', '10101100']
>>> 
>>> n = int('0010000010101100',2)
>>> chr(n)
'€'

Die farbliche Hervorhebung gewisser Bits ist natürlich von Hand hinzugefügt worden. Aber bestimmt war vorher schon alles klar und es ist kein Problem zu verstehen, aus welchen drei Teilen die Bitfolge für n zusammengesetzt wurde.

Aufgabe 4, alt

Schreibe ein Delphi-Programm zur XOR-Verschlüsselung. Der Schlüssel soll dabei - im Gegensatz zu CrypTool - durch eine ASCII-Zeichenkette dargestellt werden. Sollte der Schlüssel kürzer als der Text sein, so verlängere den Schlüssel durch Anhängen des Schlüssels. Verwende die eingebaute byteweise XOR-Verknüpfung. Die Möglichkeit, den Schlüssel zufällig zu erzeugen, wäre eine sinnvolle Erweiterung . Siehe auch: ASCII Armor

Zusatz

GUI zu Base64 base64_0.zip

auf der Python-Shell:

>>> import base64
>>> base64.b64encode(bytes('Username:Hansi','ascii'))
b'VXNlcm5hbWU6SGFuc2k='