Mateusz Mazurek – programista z pasją

Python, architektura, ciekawostki ze świata IT

Algorytmika Programowanie

Algorytm kryptograficzny XOR – Java

Cześć! Cieszę się, że mnie odwiedziłeś/aś. Zanim przejdziesz do artykułu chciałbym zwrocić Ci uwagę na to, że ten artykuł był pisany kilka lat temu (2013-02-20) miej więc proszę na uwadzę że rozwiązania i przemyślenia które tu znajdziesz nie muszą być aktualne. Niemniej jednak zachęcam do przeczytania.

Dziś od strony bezpieczeństwa.. :)
Algorytm XOR nie jest może najbezpieczniejszym algorytmem szyfrującym na świecie (przy krótkich hasłach jest mocno kiepski), ale jest prosty i nadal stanowi podstawę bardziej złożonych algorytmów takich jak np. DES. Przy spełnieniu pewnych warunków poziom bezpieczeństwa oferowany przez ten algorytm dość szybko wzrasta.
Inne nazwy to alternatywa wykluczająca czy binarne sumowanie mod 2.
Jest on tzw. szyfrem strumieniowym – czyli szyfruje każdy bit szyfrowanego tekstu.

Pierwszym krokiem algorytmu jest zamiana tekstu który szyfrujemy na odpowiednik binarny. Tworzymy z każdej litery 8 bitowe słowo binarne, zamieniając wartość litery (kod ASCII) i odpowiednio rozszerzając powstałą liczbę dwójkową.
Podobnie robimy z kluczem, czyli tekstem który będzie nam potrzeby do zaszyfrowania jak i odszyfrowania tekstu.
Co ważne, aby zaszyforwać tekst i aby go odszyfrować używać będziemy dokładnie tej samej procedury, tylko z innymi parametrami wejściowymi, ponieważ:

 a \oplus b = c [math]
c \oplus b = a[/math]

Gdzie a to nasz tekst do zaszyfrowania, b jest kluczem, a c zaszyfrowanym tekstem. Jak widzimy szyfrując zaszyfrowany tekst tym samym kluczem – odszyfrowywujemy go.
Co jest genialną właściwością.

Tablica prawdy dla XOR wygląda następująco:

a | b | w
0 | 0 | 0
0 | 1 | 1
1 | 1 | 0
1 | 0 | 1

Przejdźmy ten algorytm. Zakładam że umiesz przeliczać liczby w systemie dziesiętnym na binarny, dlatego nie użyję konkretnych słów a przykładowych ciągów zer i jedynek.

Tekst do zaszyfrowania:
0 1 0 0 0 0 1 1 1 0 1 0

Klucz:
1 1 0 1 1

Szyfrujemy:
(klucz powielamy tyle ile potrzeba)

0 1 0 0 0 0 1 1 1 0 1 0 tekst
1 1 0 1 1 1 1 0 1 1 1 1 klucz
1 0 0 1 1 1 0 1 0 1 0 1 zaszyfrowany tekst

No i teraz odszyfrujemy go :)

1 0 0 1 1 1 0 1 0 1 0 1 zaszyfrowany tekst
1 1 0 1 1 1 1 0 1 1 1 1 klucz ten sam co poprzednio
0 1 0 0 0 0 1 1 1 0 1 0 odszyfrowany tekst

Jak widać odszyfrowany tekst jest taki sam ten który chcieliśmy zaszyfrować.

Oczywiście tekst po zaszyfrowaniu będzie wyglądał conajmniej dziwnie. Ale powoli, zobaczmy na implementacje tego w Javie

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
public class krypto {
   

    String haslo_bin;// haslo w postaci binarnej
   
    String do_szyfrowania; //txt w postaci binarnej
   
    private String DectoBin(int a)
    {
       
        StringBuilder t = new StringBuilder(Integer.toBinaryString(a));//przeliczam
        int l = t.length();
        if(l<8)
        {
            for(int i=l;i<8;i++)
                t.insert(0, "0");//rozszerzam do 8 bitow
        }
    return t.toString();//zwracam
   
    }

    public krypto(String h, String haslo)
    {
    //konstruktor
    StringBuilder t = new StringBuilder();
       
    for(int i=0;i<haslo.length();i++)
        t.append(DectoBin((int)haslo.charAt(i)*2));
       
    haslo_bin=t.toString();
    StringBuilder hh = new StringBuilder();
       
    for(int i=0;i<h.length();i++)
        hh.append(DectoBin((int)h.charAt(i)));    
    do_szyfrowania=hh.toString();
//tworze w konstruktorze calosc hasla i txt do zaszyforwania
    }
   
   
    public String Go()
    {
   
        StringBuilder w = new StringBuilder();
        for(int i=0,j=0;i<do_szyfrowania.length();i++,j++){
       
            {
            if(j==haslo_bin.length()) j=0;  
            boolean a = (do_szyfrowania.charAt(i)=='1' && haslo_bin.charAt(j)=='1') || (do_szyfrowania.charAt(i)=='0' && haslo_bin.charAt(j)=='0')?true:false;
            w.append(a==true?"0":"1");
              //szyfruje, tworze ciag zer i jedynek juz zaszyfrowany
            }
       
       
        }
       
    return w.toString();//zwracam zera i jedynki
    }
   
   
    return wynik;
    }
   
    public static String toText(String a){
   
    String tt="";
    String wynik="";
     
    for(int i=0;i<a.length();i++)
    {
   
        tt=tt.concat(Character.toString(a.charAt(i)));
            if(tt.length()==8)//dziele wynik co 8
            {
         
                wynik=wynik.concat(Character.toString((char)((Integer.parseInt(tt, 2)))));    
                //po jednej literce przetwarzam na tekst
                tt="";
   
            }
       
    }
   
    return wynik;//i zwracam.
    }
   
   
}

No i wywołanie:

1
2
3
4
  public static void main(String[] args) {
     krypto t = new krypto("Programowanie jest ciekawe!", "nasz klucz",1);
     System.out.println(t.toText(t.Go()));
    }

No i w taki sposób tekst „Programowanie jest ciekawe!”, używając klucza „nasz klucz” będzie wyglądał tak:

Œ°‰“2·µ…±•²«ƒÔ*³«žæ—µ§•7³ù

:)

Pozdrawiam!

Dzięki za wizytę,
Mateusz Mazurek

A może wolisz nowości na mail?

Subskrybuj
Powiadom o
guest

Witryna wykorzystuje Akismet, aby ograniczyć spam. Dowiedz się więcej jak przetwarzane są dane komentarzy.

0 komentarzy
Inline Feedbacks
View all comments