Seminarium rozwiązywania problemów programistycznych

Transkrypt

Seminarium rozwiązywania problemów programistycznych
Seminarium rozwiązywania problemów programistycznych
Zadanie 2. Szyfr Vigenère’a
1
Wprowadzenie
Szyfrowanie jest procesem mającym na celu takie zakodowanie informacji, aby była ona dostępna tylko
dla tych osób, dla których jest przeznaczona. Istnieje wiele różnych algorytmów szyfrujących. Treścią
tego zadania jest stworzenie programu łamiącego szyfr Vigenère’a.
Zanim zapoznamy się z metodami szyfrowania konieczne będzie przedstawienie kilku podstawowych
informacji. Przyjęło się w kryptografii, że pisząc o szyfrowaniu używa się małych liter dla oznaczenia
tekstu jawnego, a wielkich dla tekstu zaszyfrowanego i będziemy tej konwencji przestrzegać w tym opisie.
Tym niemniej będziemy zakładać, że prawdziwe teksty, które będziemy szyfrowali będą się składały
wyłącznie z wielkich liter.
Nie będziemy się tu zajmowali najnowocześniejszymi szyframi i w związku z tym będziemy modyfikowali tekst przed szyfrowaniem, tak jak to robili kryptografowie, kiedy jeszcze nie wykorzystywali
do szyfrowania komputerów, Wspomniana modyfikacja polega na usunięciu z tekstu jawnego wszystkich
znaków interpunkcyjnych, spacji, znaków nowego wiersza, itd. Będziemy więc zakładali, że szyfrowany
tekst składa się wyłącznie z wielkich liter. Przyjmiemy również, że wszystkie teksty są zapisane w języku
angielskim.
2
Szyfr Cezara
Jednym z najprostszych szyfrów jest szyfr Cezara, który był już stosowany przez Juliusza Cezara. Zasada
działania tego szyfru jest bardzo prosta. Każdej literze alfabetu jawnego przyporządkowana jest litera
przesunięta w alfabecie o pewną liczbę pozycji. Przykład tablicy kodowej przedstawia rysunek 1, a na
rysunku 2 pokazany jest proces szyfrowania.
alfabet jawny
alfabet szyfrowy
a b c d e f g h i j k l m n o p q r s t u v w x y z
D E F G H I J K L M N O P Q R S T U V W X Y Z A B C
Rysunek 1: Przykładowa tablica kodowa dla szyfru Cezara z przesunięciem o 3 znaki.
tekst jawny
tekst zaszyfrowany
i a m b o n d j a m e s b o n d
L D P E R Q G M D P H V E R Q G
Rysunek 2: Szyfrowania metodą Cezara.
Jak widzimy różnych sposobów zaszyfrowania tekstu jawnego jest tylko 25, gdyż jedynie tyle mamy
różnych możliwości przesunięcia alfabetu szyfrowego. Kluczem w tym szyfrze jest odległość o jaką są
przesunięte litery alfabetu. Złamanie tego szyfru nie jest więc żadnym problemem. Wystarczy jedynie
wypróbować wszystkie 25 możliwości i sprawdzić, dla której z nich otrzymamy tekst, który ma sens.
3
Szyfr podstawieniowy
Bardziej skomplikowanym i też trudniejszym do złamania szyfrem jest szyfr podstawieniowy. Metoda
ta opiera się również na tablicy kodowej, która jest jednak tworzona w inny sposób. Każdej literze
przyporządkowywana jest litera, ale nie już nie w ten sposób, że wykonywane jest zwykłe przesunięcie
alfabetu. Przykład tablicy kodowej został przedstawiony na rysunku 3.
alfabet jawny
alfabet szyfrowy
a b c d e f g h i j k l m n o p q r s t u v w x y z
K E Q N A J Z P W G B O I X W C Y D R S F L H U M T
Rysunek 3: Przykładowa tablica kodowa dla szyfru podstawieniowego.
1
tekst jawny
tekst zaszyfrowany
i a m b o n d j a m e s b o n d
W K I E W X N G B I A R E W X N
Rysunek 4: Przykład działania szyfru podstawieniowego.
Oczywiście aby szyfr był odwracalny musimy zapewnić, aby w alfabecie szyfrowym każda litera
występowała dokładnie jeden raz. Kluczem w tej metodzie szyfrowania jest kolejność liter w alfabecie szyfrowym. Jak łatwo obliczyć, różnych możliwości wyboru klucza jest 26! = 403291461126605635584000000.
Przykład szyfrowania tym algorytmem jest przedstawiony na rysunku 4.
Proces deszyfracji jest oczywiście bardzo podobny. Wykorzystujemy tą samą tablicę kodową i dla
każdej litery tekstu zaszyfrowanego wyszukujemy odpowiadającą jej literę w alfabecie jawnym.
Ze względu dużą liczbę możliwych kluczy łamanie tego szyfru przez sprawdzenie wszystkich możliwości (atak brute force) nie jest dobrym pomysłem. O wiele lepszą metodą jest wykorzystanie tzw.
tablicy częstości, która zawiera średnią częstość wystąpień liter w tekstach zapisanych w danym języku
(w naszym wypadku w języku angielskim). Przykładową tabelę częstości pokazano na rysunku 5.
litera
a
b
c
d
e
f
g
h
i
j
k
l
m
procent
8,2
1,5
2,8
4,3
12,7
2,2
2,0
6,1
7,0
0,2
0,8
4,0
2,4
litera
n
o
p
q
r
s
t
u
v
w
x
y
z
procent
6,7
7,5
1,9
0,1
6,0
6,3
9,1
2,8
1,0
2,4
0,2
2,0
0,1
Rysunek 5: Tabela częstości występowania liter w tekstach zapisanych w języku angielskim za [1].
Jak można łatwo zauważyć najczęściej występującą literą w języku angielskim jest e, a najrzadziej
pojawiają się j, k, q, x, z. Można wykorzystać tą wiedzę i założyć, że litera w tekście zaszyfrowanym,
która pojawia się najczęściej odpowiada właśnie literze e w tekście jawnym. Podobne założenie można
uczynić dla innych liter posługując się tablicą częstości. Ze względu na fluktuacje częstości oczywiście
nie zawsze uda się nam od razu poprawnie dopasować litery, ale liczba prób dramatycznie się zmniejsza.
Można również wykorzystać fakt, że najczęściej pojawiającymi się parami liter w języku angielskim są
ss, ee, tt, ll, mm, oo. Jeśli w tekście zaszyfrowanym występują powtarzające się pary liter to z dużym
prawdopodobieństwem można założyć, że reprezentują one właśnie te litery. Bardzo często zdarza się,
że po założeniu kilku liter udaje się odczytać fragment tekstu odgadując czasami brakujące litery w
niektórych słowach. Dzięki temu uzyskujemy kolejne przyporządkowanie i systematycznie odbudowujemy
całą tablicę kodową odgadując klucz i deszyfrując wiadomość. Podejście oparte na tablicy częstości można
zastosować dlatego, że określonej literze w tekście jawnym zawsze odpowiada jedna i ta sama litera w
tekście zaszyfrowanym.
4
Szyfr Vigenère’a
Modyfikacją metody szyfrowania przez podstawienie, która usuwa wady szyfru podstawieniowego jest
szyfr Vigenère’a, który został zaproponowany w XVI wieku przez Blaise’a de Vigenr̀e’a. Autor zaproponował żeby zamiast jednego alfabetu szyfrowego zastosować ich 26. W ten sposób zbudował tzw. tablicę
Vigenère’a przedstawioną na rysunku 6.
Kolejne litery tekstu jawnego są szyfrowane przez podstawienie według jednego z alfabetów szyfrowych. O tym, który alfabet zostanie wybrany do szyfrowania kolejnej litery decyduje klucz będący
słowem (lub zbitką liku słów). Przeanalizujmy proces szyfrowania przedstawiony na rys 7. Nad tekstem
jawnym wypisujemy słowo kluczowe powtarzając je tyle razy ile to potrzebne. Następnie przeprowadzamy szyfrowanie. Dla pierwszej litery, i, wybieramy alfabet szyfrowy oznaczony przez odpowiednią literę
2
alfabet
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
jawny
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
a
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
b
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
A
c
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
A
B
d
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
A
B
C
e
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
A
B
C
D
f
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
A
B
C
D
E
g
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
A
B
C
D
E
F
h
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
A
B
C
D
E
F
G
i
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
A
B
C
D
E
F
G
H
j
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
A
B
C
D
E
F
G
H
I
k
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
A
B
C
D
E
F
G
H
I
J
l
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
A
B
C
D
E
F
G
H
I
J
K
m
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
A
B
C
D
E
F
G
H
I
J
K
L
n
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
A
B
C
D
E
F
G
H
I
J
K
L
M
o
O
P
Q
R
S
T
U
V
W
X
Y
Z
A
B
C
D
E
F
G
H
I
J
K
L
M
N
p
P
Q
R
S
T
U
V
W
X
Y
Z
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
q
Q
R
S
T
U
V
W
X
Y
Z
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
r
R
S
T
U
V
W
X
Y
Z
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
s
S
T
U
V
W
X
Y
Z
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
t
T
U
V
W
X
Y
Z
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
u
U
V
W
X
Y
Z
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
v
V
W
X
Y
Z
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
w
W
X
Y
Z
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
x
X
Y
Z
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
y
Y
Z
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
z
Z
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Rysunek 6: Tablica Vigenère’a.
klucza czyli A otrzymując zaszyfrowaną literę I. Dla drugiej litery tekstu jawnego, a, wybieramy alfabet
szyfrowy opisany przez G otrzymując zakodowaną literę G.
klucz
tekst jawny
tekst zaszyfrowany
A G E N T A G E N T A G E N T A
i a m b o n d j a m e s b o n d
I G Q O H N J N N F E Y F B G D
Rysunek 7: Szyfrowanie metodą Vigenère’a.
Siła tego algorytmu polega na tym, że do kodowania kolejnych liter wybieramy różne alfabety
szyfrowe dzięki czemu nawet jeśli jakaś litera występuje w tekście jawnym często, to jest ona kodowana na
różne litery i nie możemy już zastosować klasycznego podejścia z użyciem tablicy częstości. Jeśli w tekście
jawnym występują pary powtarzających się liter (takie jak ss, ee), to obydwie litery są kodowane na
różne sposoby i też nie możemy tego wykorzystać. Trudno też zaatakować ten szyfr stosując sprawdzenie
wszystkich możliwości, gdyż liczba możliwych kluczy wynosi 26k , gdzie k jest długością klucza użytego
do szyfrowania.
Szyfr ten uchodził przez prawie trzy stulecia za niemożliwy do złamania. Tym niemniej w XIX
wieku Charles Babbage znalazł sposób jego łamania. Zastosowanie jego podejścia jest treścią naszego
zadania.
5
Łamanie szyfru Vigenère’a
Najważniejszą obserwacją Babbage’a było to, że jeśli jakieś słowo, np. the, występuje w tekście wiele razy
to jest ono kodowane za pomocą różnych fragmentów klucza. W naszym przykładzie pierwsze wystąpienie słowa bond zostało zakodowane za pomocą fragmentu klucza NTAG, a drugie za pomocą ENTA.
Tym niemniej, jeśli słowo występuje w tekście więcej razy to istnieje duża szansa, że zostanie ono zakodowane co najmniej kilka razy za pomocą tego samego fragmentu klucza, a więc dostaniemy powtarzające
się fragmenty tekstu zaszyfrowanego, które mu odpowiadają. Regularności w tekście zaszyfrowanym są
3
właśnie tym czego szuka kryptoanalityk. Znajdując powtarzające się kilkuliterowe fragmenty w tekście
zaszyfrowanym możemy obliczyć odległości między nimi. Jeśli powtórzenia nie były dziełem przypadku,
to otrzymane odległości są wielokrotnościami długości klucza. Obliczając ich wspólne dzielniki możemy
odgadnąć jaką długość ma klucz.
Podejrzewając jaką długość ma klucz — oznaczmy ją przez k — możemy przystąpić do drugiej
części kryptoanalizy. Budujemy teraz tablice częstości liter występujących w tekście zaszyfrowanym na
tych samych pozycjach modulo k i porównujemy je ze znaną tabelą częstości wystąpień liter próbując
odgadnąć, która tablica została wykorzystana do szyfrowania, a co za tym idzie jaka jest kolejna litera
klucza. Postępując w ten sposób możemy odtworzyć cały klucz i odczytać wiadomość.
Oczywiście nie zawsze otrzymana tabela częstości będzie dokładnie odpowiadała znanej statystyce.
Czasami będziemy musieli wykonać wiele prób metodą wyszukiwania wyczerpującego aby odnaleźć właściwą literę klucza. Tym niemniej, próbować należy oczywiście w kolejności jak najlepszego dopasowania
częstości. Jeżeli trudno jest dopasować tablicę częstości dla niektórych liter klucza, można przeprowadzić wstępną analizę częściowo odczytanego tekstu poszukując najczęstszych związków liter w języku
angielskim, a w szczególności takich słów jak the, itp.
Osobnym problemem jest automatyczne sprawdzanie, czy udało się nam poprawnie odszyfrować
tekst. Dobrym pomysłem jest spróbować go „przeczytać”, tzn. pociąć go tak na fragmenty, aby następujące po sobie części były poprawnymi słowami. Do analizy należy oczywiście wykorzystać listę słów
języka angielskiego, która jest udostępniona na stronie [2]. Do efektywnego wyszukiwania w słowniku
można wykorzystać dowolne własne rozwiązania bądź gotowy kod źródłowy przeznaczony do obsługi
słownika dostępny razem z artykułem [3]. Często bieżący fragment tekstu można podzielić na słowa w
różny sposób. Jeśli określoną liczbę liter można podzielić na więcej niż jeden sposób to oczywiście bez
analizy gramatycznej, którą nie będziemy się zajmowali, nic więcej nie możemy zrobić. Często jednak
nawet jeśli kilkanaście liter da się podzielić w alternatywny sposób to po jakimś czasie okaże się, że idąc
tą drogą otrzymujemy dalej bełkot, trzeba się więc cofnąć i wybrać inny sposób podziału. Kolejnym
poważnym problemem jest to, że w tekście mogą się pojawiać słowa, których nie ma w słowniku. Mogą
to być np. nazwy własne. Jedyną metodą jest wtedy opuszczenie pewnej liczby liter odgadując w jakiś
sposób ile należy opuścić.
Na stronie [2] znajduje się przykładowy program szyfrujący i deszyfrujący algorytmem Vigenère’a,
a także prosty filtr, który przygotowuje tekst do postaci, którą akceptuje program, a więc usuwający
wszystkie znaki różne od liter i zamieniający małe litery na wielkie. Na stronie znajduje się również
zestaw zaszyfrowanych tekstów, które należy odszyfrować. Stopień trudności zadań jest zróżnicowany, a
mianowicie są dostępne teksty zaszyfrowane bardzo prostymi i krótkimi kluczami oraz z kluczami dużo
dłuższymi. Teksty różnią się także długością. Oczywiście im krótszy tekst tym trudniej jest go odczytać,
gdyż mniej regularności możemy w nim znaleźć i mniej dokładne są zbudowane tablice częstości.
Celem jest napisanie programu, który byłby w stanie łamać szyfr Vigenère’a. Na wyjściu programu
powinien pojawić się tekst z podziałem na słowa. Jeżeli jest więcej niż jeden sposób podziału to można
wyprowadzić dowolny z nich.
Literatura
[1] S. Singh, „Księga szyfrów”, Wydawnictwo Albatros A. Kuryłowicz, Warszawa 2001.
[2] http://www-zo.iinf.polsl.gliwice.pl/˜sdeor/students.htm
[3] M. Ciura, S. Deorowicz, „How to squeeze a lexicon”, Software-Practice and Experience, 2001;
31(11):1077–1090. http://www-zo.iinf.polsl.gliwice.pl/˜sdeor/pub/cd00abs.htm
4

Podobne dokumenty